diff --git a/.gitignore b/.gitignore index 577d14b..09a2a57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store .idea +.vscode agile frigate hyperbench @@ -7,6 +8,10 @@ result.html detail.js *.[oa] benchmark/ethereum/compare/ +benchmark/ethereum/erc20/eth/keystore +benchmark/ethereum/transfer/eth/keystore +benchmark/ethereum/uniswap/eth/keystore +benchmark/ethereum/keys benchmark/fabric/compare/ assets *.so diff --git a/Makefile b/Makefile index c3f36b6..b2459a0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ # Go parameters GOCMD=go -PACKR=packr GOBUILD=$(GOCMD) build GOCLEAN=$(GOCMD) clean GOTEST=$(GOCMD) test @@ -18,9 +17,6 @@ importpath=github.com/meshplus/hyperbench/cmd ldflags=-X ${importpath}.branch=${branch} -X ${importpath}.commitID=${commitID} -X ${importpath}.date=${date} # path -ASSETS=filesystem/assets -DIRS=benchmark -GET=github.com/gobuffalo/packr/v2/... github.com/gobuffalo/packr/v2/packr2 FAILPOINT=github.com/pingcap/failpoint/failpoint-ctl # export gomodule @@ -29,15 +25,10 @@ export GO111MODULE=on all: build ## build: build the binary with pre-packed static resource -build: dep assets +build: @export GOPROXY=https://goproxy.cn,direct - @packr2 build -o $(BINARY_NAME) -trimpath -ldflags "${ldflags}" - @-rm -rf $(ASSETS) - -## pack: build the binary with local static resource -pack: assets - @packr2 build -o $(BINARY_NAME) -ldflags "${ldflags}" - @-rm -rf $(ASSETS) + @$(GOCMD) mod tidy + @$(GOCMD) build -o $(BINARY_NAME) -trimpath -ldflags "${ldflags}" ## test: run all test test: @@ -48,21 +39,7 @@ test: ## clean: clean all file generated by make clean: - @packr2 clean @-rm -rf $(BINARY_NAME) - @-rm -rf $(ASSETS) - -.PHONY: assets -## assets: prepare asserts -assets: - @-rm -rf $(ASSETS) - @mkdir $(ASSETS) - @cp -r $(DIRS) $(ASSETS) - -.PHONY: dep -## dep: install the dependencies outside (may need to use proxy to download some packages) -dep: - @go get -u $(GET) help: Makefile @echo " Choose a command run in "$(PROJECTNAME)":" diff --git a/benchmark/ethereum/account_test.go b/benchmark/ethereum/account_test.go new file mode 100644 index 0000000..dcbbf8a --- /dev/null +++ b/benchmark/ethereum/account_test.go @@ -0,0 +1,125 @@ +package ethereum + +import ( + "bufio" + "crypto/ecdsa" + "encoding/hex" + "io" + "os" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" +) + +var keys = []string{ + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", + "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a", + "0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6", + "0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a", + "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba", + "0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e", + "0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356", + "0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97", + "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6", +} + +var keyFilePaths = []string{ + "transfer/eth/keystore/keys", + "invoke/eth/keystore/keys", +} + +const TotalAccount = 2000000 + +func TestAccount(t *testing.T) { + for _, key := range keys { + sk, err := crypto.HexToECDSA(strings.TrimPrefix(key, "0x")) + assert.Nil(t, err) + addr := crypto.PubkeyToAddress(sk.PublicKey) + + t.Logf("address is: %s", addr.String()) + } +} + +func TestGenerateAccount(t *testing.T) { + var dstFile *os.File + var err error + for i, keyFilePath := range keyFilePaths { + if i == 0 { + dstFile, err = os.OpenFile(keyFilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + assert.Nil(t, err) + + var sk *ecdsa.PrivateKey + for i := 0; i < TotalAccount; i++ { + sk, err = crypto.GenerateKey() + assert.Nil(t, err) + + //t.Logf("key is: %+v", *sk) + privKey := hex.EncodeToString(crypto.FromECDSA(sk)) + //t.Logf("priv key: %s", privKey) + + _, err = dstFile.Write([]byte(privKey)) + assert.Nil(t, err) + _, err = dstFile.Write([]byte("\n")) + assert.Nil(t, err) + } + err = dstFile.Close() + assert.Nil(t, err) + } else { + f, err := os.OpenFile(keyFilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + assert.Nil(t, err) + _, err = io.Copy(f, dstFile) + assert.Nil(t, err) + err = f.Close() + assert.Nil(t, err) + } + } +} + +func TestSplitAndSaveKeys(t *testing.T) { + srcFile, err := os.Open("./keys") + if err != nil { + panic(err) + } + defer srcFile.Close() + + var keys []string + scanner := bufio.NewScanner(srcFile) + for scanner.Scan() { + line := scanner.Text() + keys = append(keys, line) + } + + if err := scanner.Err(); err != nil { + panic(err) + } + + totalKeys := len(keys) + partSize := totalKeys / 3 + + part1 := keys[:partSize] + part2 := keys[partSize : 2*partSize] + part3 := keys[2*partSize:] + + paths := []string{ + "stability-erc20/eth/keystore/keys", + "stability-transfer/eth/keystore/keys", + "stability-uniswap/eth/keystore/keys"} + + for i, part := range [][]string{part1, part2, part3} { + file, err := os.Create(paths[i]) + if err != nil { + panic(err) + } + defer file.Close() + + for _, key := range part { + _, err := file.WriteString(key + "\n") + if err != nil { + panic(err) + } + } + } +} diff --git a/benchmark/ethereum/compound/config.toml b/benchmark/ethereum/compound/config.toml new file mode 100755 index 0000000..2ede3ba --- /dev/null +++ b/benchmark/ethereum/compound/config.toml @@ -0,0 +1,24 @@ +[engine] +rate = 1 # 速率,重点压测指标 +duration = "10s" # 持续时间 +cap = 2 # 客户端虚拟机数量,类似CPU核心数 +accounts = 1000 # 总账户数 + +[client] +script = "benchmark/ethereum/compound/script.lua" # 脚本 +type = "eth" # 区块链类型 +contract = "benchmark/ethereum/compound/contract" # 合约目录路径 +contract_num = 0 # 合约部署数量 +config = "benchmark/ethereum/compound/eth" # 区块链SDK配置路径 +plugin = "./eth.so" # 插件路径 +args = [] # 合约参数路径 + +[client.options] # 客户端选项 + +[recorder.log] +dump = false +dir = "./logs" +level = "info" + +[recorder.csv] +dir = "./csv" \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/CUNI.abi b/benchmark/ethereum/compound/contract/CUNI.abi new file mode 100644 index 0000000..258c78a --- /dev/null +++ b/benchmark/ethereum/compound/contract/CUNI.abi @@ -0,0 +1,1431 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "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": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + } + ], + "name": "_addReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "compLikeDelegatee", + "type": "address" + } + ], + "name": "_delegateCompLikeTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address payable", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "underlying_", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract CTokenInterface", + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract EIP20NonStandardInterface", + "name": "token", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/CUNI.bin b/benchmark/ethereum/compound/contract/CUNI.bin new file mode 100644 index 0000000..7e96f9a --- /dev/null +++ b/benchmark/ethereum/compound/contract/CUNI.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b50618c1180620000226000396000f3fe608060405234801561001057600080fd5b50600436106102f15760003560e01c80637f1e06be1161019d578063bd6d894d116100e9578063f2b3abbd116100a2578063f851a4401161007c578063f851a440146112b9578063f8f9da2814611303578063fca7820b14611321578063fe9c44ae14611363576102f1565b8063f2b3abbd14611195578063f3fdb15a146111ed578063f5e3c46214611237576102f1565b8063bd6d894d14610ff0578063c37f68e21461100e578063c5ebeaec1461107b578063db006a75146110bd578063dd62ed3e146110ff578063e9c714f214611177576102f1565b8063a0712d6811610156578063aa5af0fd11610130578063aa5af0fd14610eda578063ae9d70b014610ef8578063b2a02ff114610f16578063b71d1a0c14610f98576102f1565b8063a0712d6814610e14578063a6afed9514610e56578063a9059cbb14610e74576102f1565b80637f1e06be14610aec578063852a12e314610b305780638f840ddd14610b7257806395d89b4114610b9057806395dd919314610c1357806399d8c1b414610c6b576102f1565b8063313ce5671161025c5780635fe3b567116102155780636c540baf116101ef5780636c540baf14610a0e5780636f307dc314610a2c57806370a0823114610a7657806373acee9814610ace576102f1565b80635fe3b56714610964578063601a0bf1146109ae5780636752e702146109f0576102f1565b8063313ce567146108125780633af9e669146108365780633b1d21a21461088e5780633e941010146108ac5780634576b5db146108ee57806347bd371814610946576102f1565b8063182df0f5116102ae578063182df0f5146104b55780631a31d465146104d35780631be195601461069c57806323b872dd146106e05780632608f8181461076657806326782247146107c8576102f1565b806306fdde03146102f6578063095ea7b3146103795780630e752702146103df578063173b99041461042157806317bfdfbc1461043f57806318160ddd14610497575b600080fd5b6102fe611385565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033e578082015181840152602081019050610323565b50505050905090810190601f16801561036b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103c56004803603604081101561038f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611423565b604051808215151515815260200191505060405180910390f35b61040b600480360360208110156103f557600080fd5b810190808035906020019092919050505061151a565b6040518082815260200191505060405180910390f35b610429611532565b6040518082815260200191505060405180910390f35b6104816004803603602081101561045557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611538565b6040518082815260200191505060405180910390f35b61049f611687565b6040518082815260200191505060405180910390f35b6104bd61168d565b6040518082815260200191505060405180910390f35b61069a600480360360e08110156104e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561057057600080fd5b82018360208201111561058257600080fd5b803590602001918460018302840111640100000000831117156105a457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561060757600080fd5b82018360208201111561061957600080fd5b8035906020019184600183028401116401000000008311171561063b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611715565b005b6106de600480360360208110156106b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611811565b005b61074c600480360360608110156106f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a39565b604051808215151515815260200191505060405180910390f35b6107b26004803603604081101561077c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611b13565b6040518082815260200191505060405180910390f35b6107d0611b2d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61081a611b53565b604051808260ff1660ff16815260200191505060405180910390f35b6108786004803603602081101561084c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b66565b6040518082815260200191505060405180910390f35b610896611c6f565b6040518082815260200191505060405180910390f35b6108d8600480360360208110156108c257600080fd5b8101908080359060200190929190505050611c7e565b6040518082815260200191505060405180910390f35b6109306004803603602081101561090457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c90565b6040518082815260200191505060405180910390f35b61094e611f01565b6040518082815260200191505060405180910390f35b61096c611f07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109da600480360360208110156109c457600080fd5b8101908080359060200190929190505050611f2d565b6040518082815260200191505060405180910390f35b6109f8612033565b6040518082815260200191505060405180910390f35b610a1661203e565b6040518082815260200191505060405180910390f35b610a34612044565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610ab860048036036020811015610a8c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061206a565b6040518082815260200191505060405180910390f35b610ad66120b3565b6040518082815260200191505060405180910390f35b610b2e60048036036020811015610b0257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121fa565b005b610b5c60048036036020811015610b4657600080fd5b810190808035906020019092919050505061235c565b6040518082815260200191505060405180910390f35b610b7a61236e565b6040518082815260200191505060405180910390f35b610b98612374565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610bd8578082015181840152602081019050610bbd565b50505050905090810190601f168015610c055780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610c5560048036036020811015610c2957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612412565b6040518082815260200191505060405180910390f35b610e12600480360360c0811015610c8157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ce857600080fd5b820183602082011115610cfa57600080fd5b80359060200191846001830284011164010000000083111715610d1c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610d7f57600080fd5b820183602082011115610d9157600080fd5b80359060200191846001830284011164010000000083111715610db357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff16906020019092919050505061249d565b005b610e4060048036036020811015610e2a57600080fd5b8101908080359060200190929190505050612794565b6040518082815260200191505060405180910390f35b610e5e6127ac565b6040518082815260200191505060405180910390f35b610ec060048036036040811015610e8a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612c65565b604051808215151515815260200191505060405180910390f35b610ee2612d3e565b6040518082815260200191505060405180910390f35b610f00612d44565b6040518082815260200191505060405180910390f35b610f8260048036036060811015610f2c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612e1e565b6040518082815260200191505060405180910390f35b610fda60048036036020811015610fae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612eea565b6040518082815260200191505060405180910390f35b610ff8613069565b6040518082815260200191505060405180910390f35b6110506004803603602081101561102457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131b5565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b6110a76004803603602081101561109157600080fd5b81019080803590602001909291905050506132dd565b6040518082815260200191505060405180910390f35b6110e9600480360360208110156110d357600080fd5b81019080803590602001909291905050506132ef565b6040518082815260200191505060405180910390f35b6111616004803603604081101561111557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613301565b6040518082815260200191505060405180910390f35b61117f613388565b6040518082815260200191505060405180910390f35b6111d7600480360360208110156111ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506136a5565b6040518082815260200191505060405180910390f35b6111f56136f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6112a36004803603606081101561124d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061371b565b6040518082815260200191505060405180910390f35b6112c1613737565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61130b61375d565b6040518082815260200191505060405180910390f35b61134d6004803603602081101561133757600080fd5b810190808035906020019092919050505061382d565b6040518082815260200191505060405180910390f35b61136b613933565b604051808215151515815260200191505060405180910390f35b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561141b5780601f106113f05761010080835404028352916020019161141b565b820191906000526020600020905b8154815290600101906020018083116113fe57829003601f168201915b505050505081565b60008033905082600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040518082815260200191505060405180910390a3600191505092915050565b60008061152683613938565b50905080915050919050565b60085481565b60008060009054906101000a900460ff166115bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff021916908315150217905550600060108111156115e257fe5b6115ea6127ac565b1461165d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f61636372756520696e746572657374206661696c65640000000000000000000081525060200191505060405180910390fd5b61166682612412565b905060016000806101000a81548160ff021916908315150217905550919050565b600d5481565b600080600061169a613a4a565b91509150600060038111156116ab57fe5b8260038111156116b757fe5b1461170d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180618b286035913960400191505060405180910390fd5b809250505090565b61172386868686868661249d565b86601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117cc57600080fd5b505afa1580156117e0573d6000803e3d6000fd5b505050506040513d60208110156117f657600080fd5b81019080805190602001909291905050505050505050505050565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156118b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806189776032913960400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561193757600080fd5b505afa15801561194b573d6000803e3d6000fd5b505050506040513d602081101561196157600080fd5b810190808051906020019092919050505090508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611a1d57600080fd5b505af1158015611a31573d6000803e3d6000fd5b505050505050565b60008060009054906101000a900460ff16611abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006010811115611ae357fe5b611aef33868686613b26565b14905060016000806101000a81548160ff0219169083151502179055509392505050565b600080611b2084846140d0565b5090508091505092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900460ff1681565b6000611b706186ec565b6040518060200160405280611b83613069565b8152509050600080611bd483600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546141e4565b9150915060006003811115611be557fe5b826003811115611bf157fe5b14611c64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f62616c616e636520636f756c64206e6f742062652063616c63756c617465640081525060200191505060405180910390fd5b809350505050919050565b6000611c79614247565b905090565b6000611c898261432d565b9050919050565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cfa57611cf36001603f614439565b9050611efc565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff16627e3dd26040518163ffffffff1660e01b815260040160206040518083038186803b158015611d6657600080fd5b505afa158015611d7a573d6000803e3d6000fd5b505050506040513d6020811015611d9057600080fd5b8101908080519060200190929190505050611e13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6d61726b6572206d6574686f642072657475726e65642066616c73650000000081525060200191505060405180910390fd5b82600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d8184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a160006010811115611ef857fe5b9150505b919050565b600b5481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900460ff16611fb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000611fd46127ac565b905060006010811115611fe357fe5b811461200757611fff816010811115611ff857fe5b6030614439565b915050612014565b612010836144ad565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b666379da05b6000081565b60095481565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60008060009054906101000a900460ff16612136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000601081111561215d57fe5b6121656127ac565b146121d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f61636372756520696e746572657374206661696c65640000000000000000000081525060200191505060405180910390fd5b600b54905060016000806101000a81548160ff02191690831515021790555090565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806189d9602d913960400191505060405180910390fd5b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c19a95c826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561234157600080fd5b505af1158015612355573d6000803e3d6000fd5b5050505050565b6000612367826146be565b9050919050565b600c5481565b60028054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561240a5780601f106123df5761010080835404028352916020019161240a565b820191906000526020600020905b8154815290600101906020018083116123ed57829003601f168201915b505050505081565b6000806000612420846147c7565b915091506000600381111561243157fe5b82600381111561243d57fe5b14612493576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180618a536037913960400191505060405180910390fd5b8092505050919050565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612543576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806189306024913960400191505060405180910390fd5b600060095414801561255757506000600a54145b6125ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806189546023913960400191505060405180910390fd5b8360078190555060006007541161260e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806189a96030913960400191505060405180910390fd5b600061261987611c90565b90506000601081111561262857fe5b811461269c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f73657474696e6720636f6d7074726f6c6c6572206661696c656400000000000081525060200191505060405180910390fd5b6126a46148d2565b600981905550670de0b6b3a7640000600a819055506126c2866148da565b9050600060108111156126d157fe5b8114612728576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618a066022913960400191505060405180910390fd5b836001908051906020019061273e9291906186ff565b5082600290805190602001906127559291906186ff565b5081600360006101000a81548160ff021916908360ff16021790555060016000806101000a81548160ff02191690831515021790555050505050505050565b6000806127a083614b70565b50905080915050919050565b6000806127b76148d2565b905060006009549050818114156127de57600060108111156127d557fe5b92505050612c62565b60006127e8614247565b90506000600b5490506000600c5490506000600a5490506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315f240538686866040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b15801561288457600080fd5b505afa158015612898573d6000803e3d6000fd5b505050506040513d60208110156128ae57600080fd5b8101908080519060200190929190505050905065048c2739500081111561293d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f626f72726f772072617465206973206162737572646c7920686967680000000081525060200191505060405180910390fd5b60008061294a8989614c81565b915091506000600381111561295b57fe5b82600381111561296757fe5b146129da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f636f756c64206e6f742063616c63756c61746520626c6f636b2064656c74610081525060200191505060405180910390fd5b6129e26186ec565b600080600080612a0060405180602001604052808a81525087614cac565b809650819850505060006003811115612a1557fe5b876003811115612a2157fe5b14612a5357612a3e60096006896003811115612a3957fe5b614d2a565b9e505050505050505050505050505050612c62565b612a5d858c6141e4565b809550819850505060006003811115612a7257fe5b876003811115612a7e57fe5b14612ab057612a9b60096001896003811115612a9657fe5b614d2a565b9e505050505050505050505050505050612c62565b612aba848c614d9e565b809450819850505060006003811115612acf57fe5b876003811115612adb57fe5b14612b0d57612af860096004896003811115612af357fe5b614d2a565b9e505050505050505050505050505050612c62565b612b286040518060200160405280600854815250858c614dd0565b809350819850505060006003811115612b3d57fe5b876003811115612b4957fe5b14612b7b57612b6660096005896003811115612b6157fe5b614d2a565b9e505050505050505050505050505050612c62565b612b86858a8b614dd0565b809250819850505060006003811115612b9b57fe5b876003811115612ba757fe5b14612bd957612bc460096003896003811115612bbf57fe5b614d2a565b9e505050505050505050505050505050612c62565b8d60098190555080600a8190555082600b8190555081600c819055507f4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc048c8583866040518085815260200184815260200183815260200182815260200194505050505060405180910390a160006010811115612c5157fe5b9e5050505050505050505050505050505b90565b60008060009054906101000a900460ff16612ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006010811115612d0f57fe5b612d1b33338686613b26565b14905060016000806101000a81548160ff02191690831515021790555092915050565b600a5481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b8168816612d8c614247565b600b54600c546008546040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060206040518083038186803b158015612dde57600080fd5b505afa158015612df2573d6000803e3d6000fd5b505050506040513d6020811015612e0857600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900460ff16612ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff021916908315150217905550612ec733858585614e3b565b905060016000806101000a81548160ff0219169083151502179055509392505050565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612f5457612f4d60016045614439565b9050613064565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a98184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a16000601081111561306057fe5b9150505b919050565b60008060009054906101000a900460ff166130ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000601081111561311357fe5b61311b6127ac565b1461318e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f61636372756520696e746572657374206661696c65640000000000000000000081525060200191505060405180910390fd5b61319661168d565b905060016000806101000a81548160ff02191690831515021790555090565b6000806000806000600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600080600061320d896147c7565b80945081925050506000600381111561322257fe5b81600381111561322e57fe5b1461325f576009601081111561324057fe5b60008060008292508191508090509750975097509750505050506132d6565b613267613a4a565b80935081925050506000600381111561327c57fe5b81600381111561328857fe5b146132b9576009601081111561329a57fe5b60008060008292508191508090509750975097509750505050506132d6565b600060108111156132c657fe5b8484849750975097509750505050505b9193509193565b60006132e88261550a565b9050919050565b60006132fa82615611565b9050919050565b6000600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415806134135750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561342b5761342460016000614439565b90506136a2565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc82600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a17fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a981600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a16000601081111561369d57fe5b925050505b90565b6000806136b06127ac565b9050600060108111156136bf57fe5b81146136e3576136db8160108111156136d457fe5b6040614439565b9150506136f0565b6136ec836148da565b9150505b919050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008061372985858561571a565b509050809150509392505050565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315f240536137a5614247565b600b54600c546040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156137ed57600080fd5b505afa158015613801573d6000803e3d6000fd5b505050506040513d602081101561381757600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900460ff166138b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006138d46127ac565b9050600060108111156138e357fe5b8114613907576138ff8160108111156138f857fe5b6046614439565b915050613914565b613910836158ed565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b600181565b6000806000809054906101000a900460ff166139bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006139e06127ac565b9050600060108111156139ef57fe5b8114613a1a57613a0b816010811115613a0457fe5b6036614439565b60008090509250925050613a2b565b613a25333386615a00565b92509250505b60016000806101000a81548160ff021916908315150217905550915091565b6000806000600d5490506000811415613a6c5760006007549250925050613b22565b6000613a76614247565b90506000613a826186ec565b6000613a9384600b54600c54615fa5565b809450819250505060006003811115613aa857fe5b816003811115613ab457fe5b14613acd57806000809050965096505050505050613b22565b613ad78386616001565b809350819250505060006003811115613aec57fe5b816003811115613af857fe5b14613b1157806000809050965096505050505050613b22565b600082600001519650965050505050505b9091565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bdcdc258308787876040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b158015613c3a57600080fd5b505af1158015613c4e573d6000803e3d6000fd5b505050506040513d6020811015613c6457600080fd5b8101908080519060200190929190505050905060008114613c9457613c8c6003604a83614d2a565b9150506140c8565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415613cdc57613cd46002604b614439565b9150506140c8565b60008090508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415613d3d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9050613dbd565b600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b600080600080613dcd8589614c81565b809450819550505060006003811115613de257fe5b846003811115613dee57fe5b14613e0c57613dff6009604b614439565b96505050505050506140c8565b613e55600e60008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205489614c81565b809350819550505060006003811115613e6a57fe5b846003811115613e7657fe5b14613e9457613e876009604c614439565b96505050505050506140c8565b613edd600e60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205489614d9e565b809250819550505060006003811115613ef257fe5b846003811115613efe57fe5b14613f1c57613f0f6009604d614439565b96505050505050506140c8565b81600e60008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600e60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff851461404d5782600f60008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8a6040518082815260200191505060405180910390a3600060108111156140bf57fe5b96505050505050505b949350505050565b6000806000809054906101000a900460ff16614154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006141786127ac565b90506000601081111561418757fe5b81146141b2576141a381601081111561419c57fe5b6035614439565b600080905092509250506141c3565b6141bd338686615a00565b92509250505b60016000806101000a81548160ff0219169083151502179055509250929050565b60008060006141f16186ec565b6141fb8686614cac565b915091506000600381111561420c57fe5b82600381111561421857fe5b1461422e57816000809050935093505050614240565b6000614239826160d5565b9350935050505b9250929050565b600080601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156142ec57600080fd5b505afa158015614300573d6000803e3d6000fd5b505050506040513d602081101561431657600080fd5b810190808051906020019092919050505091505090565b60008060009054906101000a900460ff166143b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006143d46127ac565b9050600060108111156143e357fe5b8114614407576143ff8160108111156143f857fe5b604e614439565b91505061441a565b614410836160f4565b5080915050809150505b60016000806101000a81548160ff021916908315150217905550919050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601081111561446857fe5b83605081111561447457fe5b600060405180848152602001838152602001828152602001935050505060405180910390a18260108111156144a557fe5b905092915050565b600080600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146145195761451160016031614439565b9150506146b9565b6145216148d2565b6009541461453d57614535600a6033614439565b9150506146b9565b82614546614247565b101561456057614558600e6032614439565b9150506146b9565b600c5483111561457e5761457660026034614439565b9150506146b9565b82600c54039050600c548111156145e0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180618bb96024913960400191505060405180910390fd5b80600c81905550614613600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684616241565b7f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168483604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a1600060108111156146b557fe5b9150505b919050565b60008060009054906101000a900460ff16614741576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006147656127ac565b90506000601081111561477457fe5b81146147985761479081601081111561478957fe5b6027614439565b9150506147a8565b6147a4336000856163af565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b600080600080600080601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816000015414156148315760008080905095509550505050506148cd565b6148418160000154600a54616af2565b80945081955050506000600381111561485657fe5b84600381111561486257fe5b1461487a5783600080905095509550505050506148cd565b614888838260010154616b45565b80935081955050506000600381111561489d57fe5b8460038111156148a957fe5b146148c15783600080905095509550505050506148cd565b60008295509550505050505b915091565b600043905090565b600080600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146149465761493e60016042614439565b915050614b6b565b61494e6148d2565b6009541461496a57614962600a6041614439565b915050614b6b565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff16632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156149d557600080fd5b505afa1580156149e9573d6000803e3d6000fd5b505050506040513d60208110156149ff57600080fd5b8101908080519060200190929190505050614a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6d61726b6572206d6574686f642072657475726e65642066616c73650000000081525060200191505060405180910390fd5b82600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9268184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a160006010811115614b6757fe5b9150505b919050565b6000806000809054906101000a900460ff16614bf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000614c186127ac565b905060006010811115614c2757fe5b8114614c5257614c43816010811115614c3c57fe5b601e614439565b60008090509250925050614c62565b614c5c3385616b79565b92509250505b60016000806101000a81548160ff021916908315150217905550915091565b600080838311614c9957600083850391509150614ca5565b60036000809050915091505b9250929050565b6000614cb66186ec565b600080614cc7866000015186616af2565b9150915060006003811115614cd857fe5b826003811115614ce457fe5b14614d08578160405180602001604052806000815250809050935093505050614d23565b60006040518060200160405280838152508090509350935050505b9250929050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846010811115614d5957fe5b846050811115614d6557fe5b8460405180848152602001838152602001828152602001935050505060405180910390a1836010811115614d9557fe5b90509392505050565b60008060008385019050848110614dbc576000819250925050614dc9565b6002600080905092509250505b9250929050565b6000806000614ddd6186ec565b614de78787614cac565b9150915060006003811115614df857fe5b826003811115614e0457fe5b14614e1a57816000809050935093505050614e33565b614e2c614e26826160d5565b86614d9e565b9350935050505b935093915050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d02f735130888888886040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200195505050505050602060405180830381600087803b158015614f8357600080fd5b505af1158015614f97573d6000803e3d6000fd5b505050506040513d6020811015614fad57600080fd5b8101908080519060200190929190505050905060008114614fdd57614fd56003601b83614d2a565b915050615502565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156150255761501d6006601c614439565b915050615502565b61502d61877f565b615076600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485614c81565b82600001836020018281525082600381111561508e57fe5b600381111561509957fe5b8152505050600060038111156150ab57fe5b816000015160038111156150bb57fe5b146150e5576150dc6009601a836000015160038111156150d757fe5b614d2a565b92505050615502565b615104846040518060200160405280666379da05b60000815250617142565b81608001818152505061511b84826080015161716b565b81606001818152505061512c613a4a565b826000018360c0018281525082600381111561514457fe5b600381111561514f57fe5b81525050506000600381111561516157fe5b8160000151600381111561517157fe5b146151e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f65786368616e67652072617465206d617468206572726f72000000000000000081525060200191505060405180910390fd5b61520460405180602001604052808360c0015181525082608001516171b5565b8160a001818152505061521d600c548260a001516171dd565b8160e0018181525050615236600d54826080015161716b565b8161010001818152505061528d600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548260600151614d9e565b8260000183604001828152508260038111156152a557fe5b60038111156152b057fe5b8152505050600060038111156152c257fe5b816000015160038111156152d257fe5b146152fc576152f360096019836000015160038111156152ee57fe5b614d2a565b92505050615502565b8060e00151600c81905550806101000151600d819055508060200151600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060400151600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83606001516040518082815260200191505060405180910390a33073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83608001516040518082815260200191505060405180910390a37fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc5308260a001518360e00151604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a1600060108111156154fd57fe5b925050505b949350505050565b60008060009054906101000a900460ff1661558d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006155b16127ac565b9050600060108111156155c057fe5b81146155e4576155dc8160108111156155d557fe5b6008614439565b9150506155f2565b6155ee3384617227565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b60008060009054906101000a900460ff16615694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006156b86127ac565b9050600060108111156156c757fe5b81146156eb576156e38160108111156156dc57fe5b6027614439565b9150506156fb565b6156f7338460006163af565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b6000806000809054906101000a900460ff1661579e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006157c26127ac565b9050600060108111156157d157fe5b81146157fc576157ed8160108111156157e657fe5b600f614439565b600080905092509250506158cb565b8373ffffffffffffffffffffffffffffffffffffffff1663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561584457600080fd5b505af1158015615858573d6000803e3d6000fd5b505050506040513d602081101561586e57600080fd5b810190808051906020019092919050505090506000601081111561588e57fe5b81146158b9576158aa8160108111156158a357fe5b6010614439565b600080905092509250506158cb565b6158c533878787617663565b92509250505b60016000806101000a81548160ff021916908315150217905550935093915050565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146159575761595060016047614439565b90506159fb565b61595f6148d2565b6009541461597a57615973600a6048614439565b90506159fb565b670de0b6b3a764000082111561599d5761599660026049614439565b90506159fb565b60006008549050826008819055507faaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f8214608184604051808381526020018281526020019250505060405180910390a1600060108111156159f757fe5b9150505b919050565b6000806000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166324008a62308888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b158015615b1657600080fd5b505af1158015615b2a573d6000803e3d6000fd5b505050506040513d6020811015615b4057600080fd5b8101908080519060200190929190505050905060008114615b7757615b686003603883614d2a565b60008090509250925050615f9d565b615b7f6148d2565b60095414615ba257615b93600a6039614439565b60008090509250925050615f9d565b615baa6187d6565b601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154816060018181525050615bff866147c7565b826020018360800182815250826003811115615c1757fe5b6003811115615c2257fe5b815250505060006003811115615c3457fe5b81602001516003811115615c4457fe5b14615c7557615c656009603783602001516003811115615c6057fe5b614d2a565b6000809050935093505050615f9d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff851415615cb0578060800151816040018181525050615cbb565b848160400181815250505b615cc9878260400151617f5b565b8160e0018181525050615ce481608001518260e00151614c81565b826020018360a00182815250826003811115615cfc57fe5b6003811115615d0757fe5b815250505060006003811115615d1957fe5b81602001516003811115615d2957fe5b14615d7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180618a8a603a913960400191505060405180910390fd5b615d8f600b548260e00151614c81565b826020018360c00182815250826003811115615da757fe5b6003811115615db257fe5b815250505060006003811115615dc457fe5b81602001516003811115615dd457fe5b14615e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180618ac46031913960400191505060405180910390fd5b8060a00151601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600a54601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055508060c00151600b819055507f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a187878360e001518460a001518560c00151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019550505050505060405180910390a160006010811115615f9157fe5b8160e001519350935050505b935093915050565b600080600080615fb58787614d9e565b9150915060006003811115615fc657fe5b826003811115615fd257fe5b14615fe857816000809050935093505050615ff9565b615ff28186614c81565b9350935050505b935093915050565b600061600b6186ec565b60008061602086670de0b6b3a7640000616af2565b915091506000600381111561603157fe5b82600381111561603d57fe5b146160615781604051806020016040528060008152508090509350935050506160ce565b60008061606e8388616b45565b915091506000600381111561607f57fe5b82600381111561608b57fe5b146160b157816040518060200160405280600081525080905095509550505050506160ce565b600060405180602001604052808381525080905095509550505050505b9250929050565b6000670de0b6b3a76400008260000151816160ec57fe5b049050919050565b6000806000806161026148d2565b6009541461612257616116600a604f614439565b8193509350505061623c565b61612c3386617f5b565b905080600c54019150600c548210156161ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f61646420726573657276657320756e6578706563746564206f766572666c6f7781525060200191505060405180910390fd5b81600c819055507fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc5338284604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a16000601081111561623457fe5b819350935050505b915091565b6000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156162ef57600080fd5b505af1158015616303573d6000803e3d6000fd5b5050505060003d6000811461631f576020811461632957600080fd5b6000199150616335565b60206000803e60005191505b50806163a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f544f4b454e5f5452414e534645525f4f55545f4641494c45440000000000000081525060200191505060405180910390fd5b50505050565b6000808314806163bf5750600082145b616414576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180618b856034913960400191505060405180910390fd5b61641c618831565b616424613a4a565b82602001836040018281525082600381111561643c57fe5b600381111561644757fe5b81525050506000600381111561645957fe5b8160200151600381111561646957fe5b146164925761648a6009602b8360200151600381111561648557fe5b614d2a565b915050616aeb565b600084111561653457838160600181815250506164c160405180602001604052808360400151815250856141e4565b8260200183608001828152508260038111156164d957fe5b60038111156164e457fe5b8152505050600060038111156164f657fe5b8160200151600381111561650657fe5b1461652f57616527600960298360200151600381111561652257fe5b614d2a565b915050616aeb565b6165c9565b6165508360405180602001604052808460400151815250618339565b82602001836060018281525082600381111561656857fe5b600381111561657357fe5b81525050506000600381111561658557fe5b8160200151600381111561659557fe5b146165be576165b66009602a836020015160038111156165b157fe5b614d2a565b915050616aeb565b828160800181815250505b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663eabe7d91308885606001516040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156166ac57600080fd5b505af11580156166c0573d6000803e3d6000fd5b505050506040513d60208110156166d657600080fd5b8101908080519060200190929190505050905060008114616707576166fe6003602883614d2a565b92505050616aeb565b61670f6148d2565b6009541461672c57616723600a602c614439565b92505050616aeb565b61673c600d548360600151614c81565b836020018460a0018281525082600381111561675457fe5b600381111561675f57fe5b81525050506000600381111561677157fe5b8260200151600381111561678157fe5b146167ab576167a26009602e8460200151600381111561679d57fe5b614d2a565b92505050616aeb565b6167f8600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548360600151614c81565b836020018460c0018281525082600381111561681057fe5b600381111561681b57fe5b81525050506000600381111561682d57fe5b8260200151600381111561683d57fe5b146168675761685e6009602d8460200151600381111561685957fe5b614d2a565b92505050616aeb565b8160800151616874614247565b101561688f57616886600e602f614439565b92505050616aeb565b61689d868360800151616241565b8160a00151600d819055508160c00151600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84606001516040518082815260200191505060405180910390a37fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9298683608001518460600151604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a1600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166351dff9893088856080015186606001516040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b158015616ac157600080fd5b505af1158015616ad5573d6000803e3d6000fd5b5050505060006010811115616ae657fe5b925050505b9392505050565b6000806000841415616b0d5760008080905091509150616b3e565b6000838502905083858281616b1e57fe5b0414616b3557600260008090509250925050616b3e565b60008192509250505b9250929050565b6000806000831415616b61576001600080905091509150616b72565b6000838581616b6c57fe5b04915091505b9250929050565b6000806000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634ef4c3e13087876040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015616c5b57600080fd5b505af1158015616c6f573d6000803e3d6000fd5b505050506040513d6020811015616c8557600080fd5b8101908080519060200190929190505050905060008114616cbc57616cad6003601f83614d2a565b6000809050925092505061713b565b616cc46148d2565b60095414616ce757616cd8600a6022614439565b6000809050925092505061713b565b616cef618884565b616cf7613a4a565b826020018360400182815250826003811115616d0f57fe5b6003811115616d1a57fe5b815250505060006003811115616d2c57fe5b81602001516003811115616d3c57fe5b14616d6d57616d5d6009602183602001516003811115616d5857fe5b614d2a565b600080905093509350505061713b565b616d778686617f5b565b8160c0018181525050616da08160c0015160405180602001604052808460400151815250618339565b826020018360600182815250826003811115616db857fe5b6003811115616dc357fe5b815250505060006003811115616dd557fe5b81602001516003811115616de557fe5b14616e58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4d494e545f45584348414e47455f43414c43554c4154494f4e5f4641494c454481525060200191505060405180910390fd5b616e68600d548260600151614d9e565b826020018360800182815250826003811115616e8057fe5b6003811115616e8b57fe5b815250505060006003811115616e9d57fe5b81602001516003811115616ead57fe5b14616f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180618b5d6028913960400191505060405180910390fd5b616f50600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548260600151614d9e565b826020018360a00182815250826003811115616f6857fe5b6003811115616f7357fe5b815250505060006003811115616f8557fe5b81602001516003811115616f9557fe5b14616feb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180618a28602b913960400191505060405180910390fd5b8060800151600d819055508060a00151600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f868260c001518360600151604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a18573ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83606001516040518082815260200191505060405180910390a36000601081111561712f57fe5b8160c001519350935050505b9250929050565b6000670de0b6b3a764000061715b84846000015161839c565b8161716257fe5b04905092915050565b60006171ad83836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f7700000000000000000000008152506183e6565b905092915050565b60006171bf6186ec565b6171c984846184a0565b90506171d4816160d5565b91505092915050565b600061721f83836040518060400160405280601181526020017f6164646974696f6e206f766572666c6f770000000000000000000000000000008152506184cc565b905092915050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663da3d454c3086866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561730757600080fd5b505af115801561731b573d6000803e3d6000fd5b505050506040513d602081101561733157600080fd5b8101908080519060200190929190505050905060008114617361576173596003600e83614d2a565b91505061765d565b6173696148d2565b600954146173845761737c600a80614439565b91505061765d565b8261738d614247565b10156173a75761739f600e6009614439565b91505061765d565b6173af6188d7565b6173b8856147c7565b8260000183602001828152508260038111156173d057fe5b60038111156173db57fe5b8152505050600060038111156173ed57fe5b816000015160038111156173fd57fe5b146174275761741e600960078360000151600381111561741957fe5b614d2a565b9250505061765d565b617435816020015185614d9e565b82600001836040018281525082600381111561744d57fe5b600381111561745857fe5b81525050506000600381111561746a57fe5b8160000151600381111561747a57fe5b146174a45761749b6009600c8360000151600381111561749657fe5b614d2a565b9250505061765d565b6174b0600b5485614d9e565b8260000183606001828152508260038111156174c857fe5b60038111156174d357fe5b8152505050600060038111156174e557fe5b816000015160038111156174f557fe5b1461751f576175166009600b8360000151600381111561751157fe5b614d2a565b9250505061765d565b6175298585616241565b8060400151601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600a54601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055508060600151600b819055507f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80858583604001518460600151604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182815260200194505050505060405180910390a16000601081111561765857fe5b925050505b92915050565b6000806000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fc7e71e30868a8a8a6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200195505050505050602060405180830381600087803b1580156177ad57600080fd5b505af11580156177c1573d6000803e3d6000fd5b505050506040513d60208110156177d757600080fd5b810190808051906020019092919050505090506000811461780e576177ff6003601283614d2a565b60008090509250925050617f52565b6178166148d2565b600954146178395761782a600a6016614439565b60008090509250925050617f52565b6178416148d2565b8473ffffffffffffffffffffffffffffffffffffffff16636c540baf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561788757600080fd5b505afa15801561789b573d6000803e3d6000fd5b505050506040513d60208110156178b157600080fd5b8101908080519060200190929190505050146178e2576178d3600a6011614439565b60008090509250925050617f52565b8673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156179315761792260066017614439565b60008090509250925050617f52565b60008514156179555761794660076015614439565b60008090509250925050617f52565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8514156179985761798960076014614439565b60008090509250925050617f52565b6000806179a6898989615a00565b91509150600060108111156179b757fe5b82146179e4576179d38260108111156179cc57fe5b6018614439565b600080905094509450505050617f52565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c488847b308a866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604080518083038186803b158015617ac157600080fd5b505afa158015617ad5573d6000803e3d6000fd5b505050506040513d6040811015617aeb57600080fd5b8101908080519060200190929190805190602001909291905050509150915060006010811115617b1757fe5b8214617b6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180618af56033913960400191505060405180910390fd5b808873ffffffffffffffffffffffffffffffffffffffff166370a082318c6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015617bec57600080fd5b505afa158015617c00573d6000803e3d6000fd5b505050506040513d6020811015617c1657600080fd5b81019080805190602001909291905050501015617c9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f4c49515549444154455f5345495a455f544f4f5f4d554348000000000000000081525060200191505060405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff161415617ce457617cdd308d8d85614e3b565b9050617ddd565b8873ffffffffffffffffffffffffffffffffffffffff1663b2a02ff18d8d856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015617d9f57600080fd5b505af1158015617db3573d6000803e3d6000fd5b505050506040513d6020811015617dc957600080fd5b810190808051906020019092919050505090505b60006010811115617dea57fe5b8114617e5e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f746f6b656e207365697a757265206661696c656400000000000000000000000081525060200191505060405180910390fd5b7f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb528c8c868c86604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019550505050505060405180910390a160006010811115617f4657fe5b84975097505050505050505b94509492505050565b600080601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561802457600080fd5b505afa158015618038573d6000803e3d6000fd5b505050506040513d602081101561804e57600080fd5b810190808051906020019092919050505090508173ffffffffffffffffffffffffffffffffffffffff166323b872dd8630876040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561811c57600080fd5b505af1158015618130573d6000803e3d6000fd5b5050505060003d6000811461814c576020811461815657600080fd5b6000199150618162565b60206000803e60005191505b50806181d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f544f4b454e5f5452414e534645525f494e5f4641494c4544000000000000000081525060200191505060405180910390fd5b6000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561827757600080fd5b505afa15801561828b573d6000803e3d6000fd5b505050506040513d60208110156182a157600080fd5b810190808051906020019092919050505090508281101561832a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f544f4b454e5f5452414e534645525f494e5f4f564552464c4f5700000000000081525060200191505060405180910390fd5b82810394505050505092915050565b60008060006183466186ec565b618350868661858b565b915091506000600381111561836157fe5b82600381111561836d57fe5b1461838357816000809050935093505050618395565b600061838e826160d5565b9350935050505b9250929050565b60006183de83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250618607565b905092915050565b6000838311158290618493576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561845857808201518184015260208101905061843d565b50505050905090810190601f1680156184855780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b6184a86186ec565b60405180602001604052806184c185600001518561839c565b815250905092915050565b600080838501905084811015839061857f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015618544578082015181840152602081019050618529565b50505050905090810190601f1680156185715780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50809150509392505050565b60006185956186ec565b6000806185aa670de0b6b3a764000087616af2565b91509150600060038111156185bb57fe5b8260038111156185c757fe5b146185eb578160405180602001604052806000815250809050935093505050618600565b6185f9818660000151616001565b9350935050505b9250929050565b6000808414806186175750600083145b1561862557600090506186e5565b600083850290508385828161863657fe5b041483906186df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156186a4578082015181840152602081019050618689565b50505050905090810190601f1680156186d15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50809150505b9392505050565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061874057805160ff191683800117855561876e565b8280016001018555821561876e579182015b8281111561876d578251825591602001919060010190618752565b5b50905061877b919061890a565b5090565b6040518061012001604052806000600381111561879857fe5b815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806101000160405280600060108111156187ef57fe5b81526020016000600381111561880157fe5b81526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060e001604052806000601081111561884957fe5b81526020016000600381111561885b57fe5b815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060e001604052806000601081111561889c57fe5b8152602001600060038111156188ae57fe5b815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060800160405280600060038111156188ef57fe5b81526020016000815260200160008152602001600081525090565b61892c91905b80821115618928576000816000905550600101618910565b5090565b9056fe6f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e63654345726332303a3a7377656570546f6b656e3a2063616e206e6f7420737765657020756e6465726c79696e6720746f6b656e696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e6f6e6c79207468652061646d696e206d6179207365742074686520636f6d702d6c696b652064656c656761746573657474696e6720696e7465726573742072617465206d6f64656c206661696c65644d494e545f4e45575f4143434f554e545f42414c414e43455f43414c43554c4154494f4e5f4641494c4544626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e636553746f726564496e7465726e616c206661696c656452455041595f424f52524f575f4e45575f4143434f554e545f424f52524f575f42414c414e43455f43414c43554c4154494f4e5f4641494c454452455041595f424f52524f575f4e45575f544f54414c5f42414c414e43455f43414c43554c4154494f4e5f4641494c45444c49515549444154455f434f4d5054524f4c4c45525f43414c43554c4154455f414d4f554e545f5345495a455f4641494c454465786368616e67655261746553746f7265643a2065786368616e67655261746553746f726564496e7465726e616c206661696c65644d494e545f4e45575f544f54414c5f535550504c595f43414c43554c4154494f4e5f4641494c45446f6e65206f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e206d757374206265207a65726f72656475636520726573657276657320756e657870656374656420756e646572666c6f77a265627a7a72315820ba68e2fa7a2baaf6e98f64c05eddd43137feaefb30b51b0ce823cf1632ec545664736f6c63430005110032 \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/CUNI.sol b/benchmark/ethereum/compound/contract/CUNI.sol new file mode 100644 index 0000000..ddf625b --- /dev/null +++ b/benchmark/ethereum/compound/contract/CUNI.sol @@ -0,0 +1,222 @@ +pragma solidity ^0.5.16; + +import "./CToken.sol"; + +interface CompLike { + function delegate(address delegatee) external; +} + +/** + * @title Compound's CErc20 Contract + * @notice CTokens which wrap an EIP-20 underlying + * @author Compound + */ +contract CErc20 is CToken, CErc20Interface { + /** + * @notice Initialize the new money market + * @param underlying_ The address of the underlying asset + * @param comptroller_ The address of the Comptroller + * @param interestRateModel_ The address of the interest rate model + * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 + * @param name_ ERC-20 name of this token + * @param symbol_ ERC-20 symbol of this token + * @param decimals_ ERC-20 decimal precision of this token + */ + function initialize(address underlying_, + ComptrollerInterface comptroller_, + InterestRateModel interestRateModel_, + uint initialExchangeRateMantissa_, + string memory name_, + string memory symbol_, + uint8 decimals_) public { + // CToken initialize does the bulk of the work + super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_); + + // Set underlying and sanity check it + underlying = underlying_; + EIP20Interface(underlying).totalSupply(); + } + + /*** User Interface ***/ + + /** + * @notice Sender supplies assets into the market and receives cTokens in exchange + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param mintAmount The amount of the underlying asset to supply + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function mint(uint mintAmount) external returns (uint) { + (uint err,) = mintInternal(mintAmount); + return err; + } + + /** + * @notice Sender redeems cTokens in exchange for the underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemTokens The number of cTokens to redeem into underlying + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function redeem(uint redeemTokens) external returns (uint) { + return redeemInternal(redeemTokens); + } + + /** + * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemAmount The amount of underlying to redeem + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function redeemUnderlying(uint redeemAmount) external returns (uint) { + return redeemUnderlyingInternal(redeemAmount); + } + + /** + * @notice Sender borrows assets from the protocol to their own address + * @param borrowAmount The amount of the underlying asset to borrow + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function borrow(uint borrowAmount) external returns (uint) { + return borrowInternal(borrowAmount); + } + + /** + * @notice Sender repays their own borrow + * @param repayAmount The amount to repay + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function repayBorrow(uint repayAmount) external returns (uint) { + (uint err,) = repayBorrowInternal(repayAmount); + return err; + } + + /** + * @notice Sender repays a borrow belonging to borrower + * @param borrower the account with the debt being payed off + * @param repayAmount The amount to repay + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) { + (uint err,) = repayBorrowBehalfInternal(borrower, repayAmount); + return err; + } + + /** + * @notice The sender liquidates the borrowers collateral. + * The collateral seized is transferred to the liquidator. + * @param borrower The borrower of this cToken to be liquidated + * @param repayAmount The amount of the underlying borrowed asset to repay + * @param cTokenCollateral The market in which to seize collateral from the borrower + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) external returns (uint) { + (uint err,) = liquidateBorrowInternal(borrower, repayAmount, cTokenCollateral); + return err; + } + + /** + * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock) + * @param token The address of the ERC-20 token to sweep + */ + function sweepToken(EIP20NonStandardInterface token) external { + require(address(token) != underlying, "CErc20::sweepToken: can not sweep underlying token"); + uint256 balance = token.balanceOf(address(this)); + token.transfer(admin, balance); + } + + /** + * @notice The sender adds to reserves. + * @param addAmount The amount fo underlying token to add as reserves + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function _addReserves(uint addAmount) external returns (uint) { + return _addReservesInternal(addAmount); + } + + /*** Safe Token ***/ + + /** + * @notice Gets balance of this contract in terms of the underlying + * @dev This excludes the value of the current message, if any + * @return The quantity of underlying tokens owned by this contract + */ + function getCashPrior() internal view returns (uint) { + EIP20Interface token = EIP20Interface(underlying); + return token.balanceOf(address(this)); + } + + /** + * @dev Similar to EIP20 transfer, except it handles a False result from `transferFrom` and reverts in that case. + * This will revert due to insufficient balance or insufficient allowance. + * This function returns the actual amount received, + * which may be less than `amount` if there is a fee attached to the transfer. + * + * Note: This wrapper safely handles non-standard ERC-20 tokens that do not return a value. + * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca + */ + function doTransferIn(address from, uint amount) internal returns (uint) { + EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying); + uint balanceBefore = EIP20Interface(underlying).balanceOf(address(this)); + token.transferFrom(from, address(this), amount); + + bool success; + assembly { + switch returndatasize() + case 0 { // This is a non-standard ERC-20 + success := not(0) // set success to true + } + case 32 { // This is a compliant ERC-20 + returndatacopy(0, 0, 32) + success := mload(0) // Set `success = returndata` of external call + } + default { // This is an excessively non-compliant ERC-20, revert. + revert(0, 0) + } + } + require(success, "TOKEN_TRANSFER_IN_FAILED"); + + // Calculate the amount that was *actually* transferred + uint balanceAfter = EIP20Interface(underlying).balanceOf(address(this)); + require(balanceAfter >= balanceBefore, "TOKEN_TRANSFER_IN_OVERFLOW"); + return balanceAfter - balanceBefore; // underflow already checked above, just subtract + } + + /** + * @dev Similar to EIP20 transfer, except it handles a False success from `transfer` and returns an explanatory + * error code rather than reverting. If caller has not called checked protocol's balance, this may revert due to + * insufficient cash held in this contract. If caller has checked protocol's balance prior to this call, and verified + * it is >= amount, this should not revert in normal conditions. + * + * Note: This wrapper safely handles non-standard ERC-20 tokens that do not return a value. + * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca + */ + function doTransferOut(address payable to, uint amount) internal { + EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying); + token.transfer(to, amount); + + bool success; + assembly { + switch returndatasize() + case 0 { // This is a non-standard ERC-20 + success := not(0) // set success to true + } + case 32 { // This is a compliant ERC-20 + returndatacopy(0, 0, 32) + success := mload(0) // Set `success = returndata` of external call + } + default { // This is an excessively non-compliant ERC-20, revert. + revert(0, 0) + } + } + require(success, "TOKEN_TRANSFER_OUT_FAILED"); + } + + /** + * @notice Admin call to delegate the votes of the COMP-like underlying + * @param compLikeDelegatee The address to delegate votes to + * @dev CTokens whose underlying are not CompLike should revert here + */ + function _delegateCompLikeTo(address compLikeDelegatee) external { + require(msg.sender == admin, "only the admin may set the comp-like delegate"); + CompLike(underlying).delegate(compLikeDelegatee); + } +} diff --git a/benchmark/ethereum/compound/contract/CUSDC.abi b/benchmark/ethereum/compound/contract/CUSDC.abi new file mode 100644 index 0000000..258c78a --- /dev/null +++ b/benchmark/ethereum/compound/contract/CUSDC.abi @@ -0,0 +1,1431 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "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": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + } + ], + "name": "_addReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "compLikeDelegatee", + "type": "address" + } + ], + "name": "_delegateCompLikeTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address payable", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "underlying_", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract CTokenInterface", + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract EIP20NonStandardInterface", + "name": "token", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/CUSDC.bin b/benchmark/ethereum/compound/contract/CUSDC.bin new file mode 100644 index 0000000..7e96f9a --- /dev/null +++ b/benchmark/ethereum/compound/contract/CUSDC.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b50618c1180620000226000396000f3fe608060405234801561001057600080fd5b50600436106102f15760003560e01c80637f1e06be1161019d578063bd6d894d116100e9578063f2b3abbd116100a2578063f851a4401161007c578063f851a440146112b9578063f8f9da2814611303578063fca7820b14611321578063fe9c44ae14611363576102f1565b8063f2b3abbd14611195578063f3fdb15a146111ed578063f5e3c46214611237576102f1565b8063bd6d894d14610ff0578063c37f68e21461100e578063c5ebeaec1461107b578063db006a75146110bd578063dd62ed3e146110ff578063e9c714f214611177576102f1565b8063a0712d6811610156578063aa5af0fd11610130578063aa5af0fd14610eda578063ae9d70b014610ef8578063b2a02ff114610f16578063b71d1a0c14610f98576102f1565b8063a0712d6814610e14578063a6afed9514610e56578063a9059cbb14610e74576102f1565b80637f1e06be14610aec578063852a12e314610b305780638f840ddd14610b7257806395d89b4114610b9057806395dd919314610c1357806399d8c1b414610c6b576102f1565b8063313ce5671161025c5780635fe3b567116102155780636c540baf116101ef5780636c540baf14610a0e5780636f307dc314610a2c57806370a0823114610a7657806373acee9814610ace576102f1565b80635fe3b56714610964578063601a0bf1146109ae5780636752e702146109f0576102f1565b8063313ce567146108125780633af9e669146108365780633b1d21a21461088e5780633e941010146108ac5780634576b5db146108ee57806347bd371814610946576102f1565b8063182df0f5116102ae578063182df0f5146104b55780631a31d465146104d35780631be195601461069c57806323b872dd146106e05780632608f8181461076657806326782247146107c8576102f1565b806306fdde03146102f6578063095ea7b3146103795780630e752702146103df578063173b99041461042157806317bfdfbc1461043f57806318160ddd14610497575b600080fd5b6102fe611385565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033e578082015181840152602081019050610323565b50505050905090810190601f16801561036b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103c56004803603604081101561038f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611423565b604051808215151515815260200191505060405180910390f35b61040b600480360360208110156103f557600080fd5b810190808035906020019092919050505061151a565b6040518082815260200191505060405180910390f35b610429611532565b6040518082815260200191505060405180910390f35b6104816004803603602081101561045557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611538565b6040518082815260200191505060405180910390f35b61049f611687565b6040518082815260200191505060405180910390f35b6104bd61168d565b6040518082815260200191505060405180910390f35b61069a600480360360e08110156104e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561057057600080fd5b82018360208201111561058257600080fd5b803590602001918460018302840111640100000000831117156105a457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561060757600080fd5b82018360208201111561061957600080fd5b8035906020019184600183028401116401000000008311171561063b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611715565b005b6106de600480360360208110156106b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611811565b005b61074c600480360360608110156106f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a39565b604051808215151515815260200191505060405180910390f35b6107b26004803603604081101561077c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611b13565b6040518082815260200191505060405180910390f35b6107d0611b2d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61081a611b53565b604051808260ff1660ff16815260200191505060405180910390f35b6108786004803603602081101561084c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b66565b6040518082815260200191505060405180910390f35b610896611c6f565b6040518082815260200191505060405180910390f35b6108d8600480360360208110156108c257600080fd5b8101908080359060200190929190505050611c7e565b6040518082815260200191505060405180910390f35b6109306004803603602081101561090457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c90565b6040518082815260200191505060405180910390f35b61094e611f01565b6040518082815260200191505060405180910390f35b61096c611f07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109da600480360360208110156109c457600080fd5b8101908080359060200190929190505050611f2d565b6040518082815260200191505060405180910390f35b6109f8612033565b6040518082815260200191505060405180910390f35b610a1661203e565b6040518082815260200191505060405180910390f35b610a34612044565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610ab860048036036020811015610a8c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061206a565b6040518082815260200191505060405180910390f35b610ad66120b3565b6040518082815260200191505060405180910390f35b610b2e60048036036020811015610b0257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121fa565b005b610b5c60048036036020811015610b4657600080fd5b810190808035906020019092919050505061235c565b6040518082815260200191505060405180910390f35b610b7a61236e565b6040518082815260200191505060405180910390f35b610b98612374565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610bd8578082015181840152602081019050610bbd565b50505050905090810190601f168015610c055780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610c5560048036036020811015610c2957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612412565b6040518082815260200191505060405180910390f35b610e12600480360360c0811015610c8157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ce857600080fd5b820183602082011115610cfa57600080fd5b80359060200191846001830284011164010000000083111715610d1c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610d7f57600080fd5b820183602082011115610d9157600080fd5b80359060200191846001830284011164010000000083111715610db357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff16906020019092919050505061249d565b005b610e4060048036036020811015610e2a57600080fd5b8101908080359060200190929190505050612794565b6040518082815260200191505060405180910390f35b610e5e6127ac565b6040518082815260200191505060405180910390f35b610ec060048036036040811015610e8a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612c65565b604051808215151515815260200191505060405180910390f35b610ee2612d3e565b6040518082815260200191505060405180910390f35b610f00612d44565b6040518082815260200191505060405180910390f35b610f8260048036036060811015610f2c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612e1e565b6040518082815260200191505060405180910390f35b610fda60048036036020811015610fae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612eea565b6040518082815260200191505060405180910390f35b610ff8613069565b6040518082815260200191505060405180910390f35b6110506004803603602081101561102457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131b5565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b6110a76004803603602081101561109157600080fd5b81019080803590602001909291905050506132dd565b6040518082815260200191505060405180910390f35b6110e9600480360360208110156110d357600080fd5b81019080803590602001909291905050506132ef565b6040518082815260200191505060405180910390f35b6111616004803603604081101561111557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613301565b6040518082815260200191505060405180910390f35b61117f613388565b6040518082815260200191505060405180910390f35b6111d7600480360360208110156111ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506136a5565b6040518082815260200191505060405180910390f35b6111f56136f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6112a36004803603606081101561124d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061371b565b6040518082815260200191505060405180910390f35b6112c1613737565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61130b61375d565b6040518082815260200191505060405180910390f35b61134d6004803603602081101561133757600080fd5b810190808035906020019092919050505061382d565b6040518082815260200191505060405180910390f35b61136b613933565b604051808215151515815260200191505060405180910390f35b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561141b5780601f106113f05761010080835404028352916020019161141b565b820191906000526020600020905b8154815290600101906020018083116113fe57829003601f168201915b505050505081565b60008033905082600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040518082815260200191505060405180910390a3600191505092915050565b60008061152683613938565b50905080915050919050565b60085481565b60008060009054906101000a900460ff166115bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff021916908315150217905550600060108111156115e257fe5b6115ea6127ac565b1461165d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f61636372756520696e746572657374206661696c65640000000000000000000081525060200191505060405180910390fd5b61166682612412565b905060016000806101000a81548160ff021916908315150217905550919050565b600d5481565b600080600061169a613a4a565b91509150600060038111156116ab57fe5b8260038111156116b757fe5b1461170d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180618b286035913960400191505060405180910390fd5b809250505090565b61172386868686868661249d565b86601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117cc57600080fd5b505afa1580156117e0573d6000803e3d6000fd5b505050506040513d60208110156117f657600080fd5b81019080805190602001909291905050505050505050505050565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156118b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806189776032913960400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561193757600080fd5b505afa15801561194b573d6000803e3d6000fd5b505050506040513d602081101561196157600080fd5b810190808051906020019092919050505090508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611a1d57600080fd5b505af1158015611a31573d6000803e3d6000fd5b505050505050565b60008060009054906101000a900460ff16611abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006010811115611ae357fe5b611aef33868686613b26565b14905060016000806101000a81548160ff0219169083151502179055509392505050565b600080611b2084846140d0565b5090508091505092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900460ff1681565b6000611b706186ec565b6040518060200160405280611b83613069565b8152509050600080611bd483600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546141e4565b9150915060006003811115611be557fe5b826003811115611bf157fe5b14611c64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f62616c616e636520636f756c64206e6f742062652063616c63756c617465640081525060200191505060405180910390fd5b809350505050919050565b6000611c79614247565b905090565b6000611c898261432d565b9050919050565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cfa57611cf36001603f614439565b9050611efc565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff16627e3dd26040518163ffffffff1660e01b815260040160206040518083038186803b158015611d6657600080fd5b505afa158015611d7a573d6000803e3d6000fd5b505050506040513d6020811015611d9057600080fd5b8101908080519060200190929190505050611e13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6d61726b6572206d6574686f642072657475726e65642066616c73650000000081525060200191505060405180910390fd5b82600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d8184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a160006010811115611ef857fe5b9150505b919050565b600b5481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900460ff16611fb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000611fd46127ac565b905060006010811115611fe357fe5b811461200757611fff816010811115611ff857fe5b6030614439565b915050612014565b612010836144ad565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b666379da05b6000081565b60095481565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60008060009054906101000a900460ff16612136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000601081111561215d57fe5b6121656127ac565b146121d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f61636372756520696e746572657374206661696c65640000000000000000000081525060200191505060405180910390fd5b600b54905060016000806101000a81548160ff02191690831515021790555090565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806189d9602d913960400191505060405180910390fd5b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c19a95c826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561234157600080fd5b505af1158015612355573d6000803e3d6000fd5b5050505050565b6000612367826146be565b9050919050565b600c5481565b60028054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561240a5780601f106123df5761010080835404028352916020019161240a565b820191906000526020600020905b8154815290600101906020018083116123ed57829003601f168201915b505050505081565b6000806000612420846147c7565b915091506000600381111561243157fe5b82600381111561243d57fe5b14612493576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180618a536037913960400191505060405180910390fd5b8092505050919050565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612543576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806189306024913960400191505060405180910390fd5b600060095414801561255757506000600a54145b6125ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806189546023913960400191505060405180910390fd5b8360078190555060006007541161260e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806189a96030913960400191505060405180910390fd5b600061261987611c90565b90506000601081111561262857fe5b811461269c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f73657474696e6720636f6d7074726f6c6c6572206661696c656400000000000081525060200191505060405180910390fd5b6126a46148d2565b600981905550670de0b6b3a7640000600a819055506126c2866148da565b9050600060108111156126d157fe5b8114612728576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618a066022913960400191505060405180910390fd5b836001908051906020019061273e9291906186ff565b5082600290805190602001906127559291906186ff565b5081600360006101000a81548160ff021916908360ff16021790555060016000806101000a81548160ff02191690831515021790555050505050505050565b6000806127a083614b70565b50905080915050919050565b6000806127b76148d2565b905060006009549050818114156127de57600060108111156127d557fe5b92505050612c62565b60006127e8614247565b90506000600b5490506000600c5490506000600a5490506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315f240538686866040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b15801561288457600080fd5b505afa158015612898573d6000803e3d6000fd5b505050506040513d60208110156128ae57600080fd5b8101908080519060200190929190505050905065048c2739500081111561293d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f626f72726f772072617465206973206162737572646c7920686967680000000081525060200191505060405180910390fd5b60008061294a8989614c81565b915091506000600381111561295b57fe5b82600381111561296757fe5b146129da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f636f756c64206e6f742063616c63756c61746520626c6f636b2064656c74610081525060200191505060405180910390fd5b6129e26186ec565b600080600080612a0060405180602001604052808a81525087614cac565b809650819850505060006003811115612a1557fe5b876003811115612a2157fe5b14612a5357612a3e60096006896003811115612a3957fe5b614d2a565b9e505050505050505050505050505050612c62565b612a5d858c6141e4565b809550819850505060006003811115612a7257fe5b876003811115612a7e57fe5b14612ab057612a9b60096001896003811115612a9657fe5b614d2a565b9e505050505050505050505050505050612c62565b612aba848c614d9e565b809450819850505060006003811115612acf57fe5b876003811115612adb57fe5b14612b0d57612af860096004896003811115612af357fe5b614d2a565b9e505050505050505050505050505050612c62565b612b286040518060200160405280600854815250858c614dd0565b809350819850505060006003811115612b3d57fe5b876003811115612b4957fe5b14612b7b57612b6660096005896003811115612b6157fe5b614d2a565b9e505050505050505050505050505050612c62565b612b86858a8b614dd0565b809250819850505060006003811115612b9b57fe5b876003811115612ba757fe5b14612bd957612bc460096003896003811115612bbf57fe5b614d2a565b9e505050505050505050505050505050612c62565b8d60098190555080600a8190555082600b8190555081600c819055507f4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc048c8583866040518085815260200184815260200183815260200182815260200194505050505060405180910390a160006010811115612c5157fe5b9e5050505050505050505050505050505b90565b60008060009054906101000a900460ff16612ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006010811115612d0f57fe5b612d1b33338686613b26565b14905060016000806101000a81548160ff02191690831515021790555092915050565b600a5481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b8168816612d8c614247565b600b54600c546008546040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060206040518083038186803b158015612dde57600080fd5b505afa158015612df2573d6000803e3d6000fd5b505050506040513d6020811015612e0857600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900460ff16612ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff021916908315150217905550612ec733858585614e3b565b905060016000806101000a81548160ff0219169083151502179055509392505050565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612f5457612f4d60016045614439565b9050613064565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a98184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a16000601081111561306057fe5b9150505b919050565b60008060009054906101000a900460ff166130ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000601081111561311357fe5b61311b6127ac565b1461318e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f61636372756520696e746572657374206661696c65640000000000000000000081525060200191505060405180910390fd5b61319661168d565b905060016000806101000a81548160ff02191690831515021790555090565b6000806000806000600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600080600061320d896147c7565b80945081925050506000600381111561322257fe5b81600381111561322e57fe5b1461325f576009601081111561324057fe5b60008060008292508191508090509750975097509750505050506132d6565b613267613a4a565b80935081925050506000600381111561327c57fe5b81600381111561328857fe5b146132b9576009601081111561329a57fe5b60008060008292508191508090509750975097509750505050506132d6565b600060108111156132c657fe5b8484849750975097509750505050505b9193509193565b60006132e88261550a565b9050919050565b60006132fa82615611565b9050919050565b6000600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415806134135750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561342b5761342460016000614439565b90506136a2565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc82600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a17fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a981600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a16000601081111561369d57fe5b925050505b90565b6000806136b06127ac565b9050600060108111156136bf57fe5b81146136e3576136db8160108111156136d457fe5b6040614439565b9150506136f0565b6136ec836148da565b9150505b919050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008061372985858561571a565b509050809150509392505050565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315f240536137a5614247565b600b54600c546040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156137ed57600080fd5b505afa158015613801573d6000803e3d6000fd5b505050506040513d602081101561381757600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900460ff166138b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006138d46127ac565b9050600060108111156138e357fe5b8114613907576138ff8160108111156138f857fe5b6046614439565b915050613914565b613910836158ed565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b600181565b6000806000809054906101000a900460ff166139bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006139e06127ac565b9050600060108111156139ef57fe5b8114613a1a57613a0b816010811115613a0457fe5b6036614439565b60008090509250925050613a2b565b613a25333386615a00565b92509250505b60016000806101000a81548160ff021916908315150217905550915091565b6000806000600d5490506000811415613a6c5760006007549250925050613b22565b6000613a76614247565b90506000613a826186ec565b6000613a9384600b54600c54615fa5565b809450819250505060006003811115613aa857fe5b816003811115613ab457fe5b14613acd57806000809050965096505050505050613b22565b613ad78386616001565b809350819250505060006003811115613aec57fe5b816003811115613af857fe5b14613b1157806000809050965096505050505050613b22565b600082600001519650965050505050505b9091565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bdcdc258308787876040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b158015613c3a57600080fd5b505af1158015613c4e573d6000803e3d6000fd5b505050506040513d6020811015613c6457600080fd5b8101908080519060200190929190505050905060008114613c9457613c8c6003604a83614d2a565b9150506140c8565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415613cdc57613cd46002604b614439565b9150506140c8565b60008090508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415613d3d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9050613dbd565b600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b600080600080613dcd8589614c81565b809450819550505060006003811115613de257fe5b846003811115613dee57fe5b14613e0c57613dff6009604b614439565b96505050505050506140c8565b613e55600e60008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205489614c81565b809350819550505060006003811115613e6a57fe5b846003811115613e7657fe5b14613e9457613e876009604c614439565b96505050505050506140c8565b613edd600e60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205489614d9e565b809250819550505060006003811115613ef257fe5b846003811115613efe57fe5b14613f1c57613f0f6009604d614439565b96505050505050506140c8565b81600e60008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600e60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff851461404d5782600f60008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8a6040518082815260200191505060405180910390a3600060108111156140bf57fe5b96505050505050505b949350505050565b6000806000809054906101000a900460ff16614154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006141786127ac565b90506000601081111561418757fe5b81146141b2576141a381601081111561419c57fe5b6035614439565b600080905092509250506141c3565b6141bd338686615a00565b92509250505b60016000806101000a81548160ff0219169083151502179055509250929050565b60008060006141f16186ec565b6141fb8686614cac565b915091506000600381111561420c57fe5b82600381111561421857fe5b1461422e57816000809050935093505050614240565b6000614239826160d5565b9350935050505b9250929050565b600080601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156142ec57600080fd5b505afa158015614300573d6000803e3d6000fd5b505050506040513d602081101561431657600080fd5b810190808051906020019092919050505091505090565b60008060009054906101000a900460ff166143b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006143d46127ac565b9050600060108111156143e357fe5b8114614407576143ff8160108111156143f857fe5b604e614439565b91505061441a565b614410836160f4565b5080915050809150505b60016000806101000a81548160ff021916908315150217905550919050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601081111561446857fe5b83605081111561447457fe5b600060405180848152602001838152602001828152602001935050505060405180910390a18260108111156144a557fe5b905092915050565b600080600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146145195761451160016031614439565b9150506146b9565b6145216148d2565b6009541461453d57614535600a6033614439565b9150506146b9565b82614546614247565b101561456057614558600e6032614439565b9150506146b9565b600c5483111561457e5761457660026034614439565b9150506146b9565b82600c54039050600c548111156145e0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180618bb96024913960400191505060405180910390fd5b80600c81905550614613600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684616241565b7f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168483604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a1600060108111156146b557fe5b9150505b919050565b60008060009054906101000a900460ff16614741576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006147656127ac565b90506000601081111561477457fe5b81146147985761479081601081111561478957fe5b6027614439565b9150506147a8565b6147a4336000856163af565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b600080600080600080601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816000015414156148315760008080905095509550505050506148cd565b6148418160000154600a54616af2565b80945081955050506000600381111561485657fe5b84600381111561486257fe5b1461487a5783600080905095509550505050506148cd565b614888838260010154616b45565b80935081955050506000600381111561489d57fe5b8460038111156148a957fe5b146148c15783600080905095509550505050506148cd565b60008295509550505050505b915091565b600043905090565b600080600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146149465761493e60016042614439565b915050614b6b565b61494e6148d2565b6009541461496a57614962600a6041614439565b915050614b6b565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff16632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156149d557600080fd5b505afa1580156149e9573d6000803e3d6000fd5b505050506040513d60208110156149ff57600080fd5b8101908080519060200190929190505050614a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6d61726b6572206d6574686f642072657475726e65642066616c73650000000081525060200191505060405180910390fd5b82600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9268184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a160006010811115614b6757fe5b9150505b919050565b6000806000809054906101000a900460ff16614bf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff0219169083151502179055506000614c186127ac565b905060006010811115614c2757fe5b8114614c5257614c43816010811115614c3c57fe5b601e614439565b60008090509250925050614c62565b614c5c3385616b79565b92509250505b60016000806101000a81548160ff021916908315150217905550915091565b600080838311614c9957600083850391509150614ca5565b60036000809050915091505b9250929050565b6000614cb66186ec565b600080614cc7866000015186616af2565b9150915060006003811115614cd857fe5b826003811115614ce457fe5b14614d08578160405180602001604052806000815250809050935093505050614d23565b60006040518060200160405280838152508090509350935050505b9250929050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846010811115614d5957fe5b846050811115614d6557fe5b8460405180848152602001838152602001828152602001935050505060405180910390a1836010811115614d9557fe5b90509392505050565b60008060008385019050848110614dbc576000819250925050614dc9565b6002600080905092509250505b9250929050565b6000806000614ddd6186ec565b614de78787614cac565b9150915060006003811115614df857fe5b826003811115614e0457fe5b14614e1a57816000809050935093505050614e33565b614e2c614e26826160d5565b86614d9e565b9350935050505b935093915050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d02f735130888888886040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200195505050505050602060405180830381600087803b158015614f8357600080fd5b505af1158015614f97573d6000803e3d6000fd5b505050506040513d6020811015614fad57600080fd5b8101908080519060200190929190505050905060008114614fdd57614fd56003601b83614d2a565b915050615502565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156150255761501d6006601c614439565b915050615502565b61502d61877f565b615076600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485614c81565b82600001836020018281525082600381111561508e57fe5b600381111561509957fe5b8152505050600060038111156150ab57fe5b816000015160038111156150bb57fe5b146150e5576150dc6009601a836000015160038111156150d757fe5b614d2a565b92505050615502565b615104846040518060200160405280666379da05b60000815250617142565b81608001818152505061511b84826080015161716b565b81606001818152505061512c613a4a565b826000018360c0018281525082600381111561514457fe5b600381111561514f57fe5b81525050506000600381111561516157fe5b8160000151600381111561517157fe5b146151e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f65786368616e67652072617465206d617468206572726f72000000000000000081525060200191505060405180910390fd5b61520460405180602001604052808360c0015181525082608001516171b5565b8160a001818152505061521d600c548260a001516171dd565b8160e0018181525050615236600d54826080015161716b565b8161010001818152505061528d600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548260600151614d9e565b8260000183604001828152508260038111156152a557fe5b60038111156152b057fe5b8152505050600060038111156152c257fe5b816000015160038111156152d257fe5b146152fc576152f360096019836000015160038111156152ee57fe5b614d2a565b92505050615502565b8060e00151600c81905550806101000151600d819055508060200151600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060400151600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83606001516040518082815260200191505060405180910390a33073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83608001516040518082815260200191505060405180910390a37fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc5308260a001518360e00151604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a1600060108111156154fd57fe5b925050505b949350505050565b60008060009054906101000a900460ff1661558d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006155b16127ac565b9050600060108111156155c057fe5b81146155e4576155dc8160108111156155d557fe5b6008614439565b9150506155f2565b6155ee3384617227565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b60008060009054906101000a900460ff16615694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006156b86127ac565b9050600060108111156156c757fe5b81146156eb576156e38160108111156156dc57fe5b6027614439565b9150506156fb565b6156f7338460006163af565b9150505b60016000806101000a81548160ff021916908315150217905550919050565b6000806000809054906101000a900460ff1661579e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f72652d656e74657265640000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008060006101000a81548160ff02191690831515021790555060006157c26127ac565b9050600060108111156157d157fe5b81146157fc576157ed8160108111156157e657fe5b600f614439565b600080905092509250506158cb565b8373ffffffffffffffffffffffffffffffffffffffff1663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561584457600080fd5b505af1158015615858573d6000803e3d6000fd5b505050506040513d602081101561586e57600080fd5b810190808051906020019092919050505090506000601081111561588e57fe5b81146158b9576158aa8160108111156158a357fe5b6010614439565b600080905092509250506158cb565b6158c533878787617663565b92509250505b60016000806101000a81548160ff021916908315150217905550935093915050565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146159575761595060016047614439565b90506159fb565b61595f6148d2565b6009541461597a57615973600a6048614439565b90506159fb565b670de0b6b3a764000082111561599d5761599660026049614439565b90506159fb565b60006008549050826008819055507faaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f8214608184604051808381526020018281526020019250505060405180910390a1600060108111156159f757fe5b9150505b919050565b6000806000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166324008a62308888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b158015615b1657600080fd5b505af1158015615b2a573d6000803e3d6000fd5b505050506040513d6020811015615b4057600080fd5b8101908080519060200190929190505050905060008114615b7757615b686003603883614d2a565b60008090509250925050615f9d565b615b7f6148d2565b60095414615ba257615b93600a6039614439565b60008090509250925050615f9d565b615baa6187d6565b601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154816060018181525050615bff866147c7565b826020018360800182815250826003811115615c1757fe5b6003811115615c2257fe5b815250505060006003811115615c3457fe5b81602001516003811115615c4457fe5b14615c7557615c656009603783602001516003811115615c6057fe5b614d2a565b6000809050935093505050615f9d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff851415615cb0578060800151816040018181525050615cbb565b848160400181815250505b615cc9878260400151617f5b565b8160e0018181525050615ce481608001518260e00151614c81565b826020018360a00182815250826003811115615cfc57fe5b6003811115615d0757fe5b815250505060006003811115615d1957fe5b81602001516003811115615d2957fe5b14615d7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180618a8a603a913960400191505060405180910390fd5b615d8f600b548260e00151614c81565b826020018360c00182815250826003811115615da757fe5b6003811115615db257fe5b815250505060006003811115615dc457fe5b81602001516003811115615dd457fe5b14615e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180618ac46031913960400191505060405180910390fd5b8060a00151601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600a54601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055508060c00151600b819055507f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a187878360e001518460a001518560c00151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019550505050505060405180910390a160006010811115615f9157fe5b8160e001519350935050505b935093915050565b600080600080615fb58787614d9e565b9150915060006003811115615fc657fe5b826003811115615fd257fe5b14615fe857816000809050935093505050615ff9565b615ff28186614c81565b9350935050505b935093915050565b600061600b6186ec565b60008061602086670de0b6b3a7640000616af2565b915091506000600381111561603157fe5b82600381111561603d57fe5b146160615781604051806020016040528060008152508090509350935050506160ce565b60008061606e8388616b45565b915091506000600381111561607f57fe5b82600381111561608b57fe5b146160b157816040518060200160405280600081525080905095509550505050506160ce565b600060405180602001604052808381525080905095509550505050505b9250929050565b6000670de0b6b3a76400008260000151816160ec57fe5b049050919050565b6000806000806161026148d2565b6009541461612257616116600a604f614439565b8193509350505061623c565b61612c3386617f5b565b905080600c54019150600c548210156161ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f61646420726573657276657320756e6578706563746564206f766572666c6f7781525060200191505060405180910390fd5b81600c819055507fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc5338284604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a16000601081111561623457fe5b819350935050505b915091565b6000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156162ef57600080fd5b505af1158015616303573d6000803e3d6000fd5b5050505060003d6000811461631f576020811461632957600080fd5b6000199150616335565b60206000803e60005191505b50806163a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f544f4b454e5f5452414e534645525f4f55545f4641494c45440000000000000081525060200191505060405180910390fd5b50505050565b6000808314806163bf5750600082145b616414576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180618b856034913960400191505060405180910390fd5b61641c618831565b616424613a4a565b82602001836040018281525082600381111561643c57fe5b600381111561644757fe5b81525050506000600381111561645957fe5b8160200151600381111561646957fe5b146164925761648a6009602b8360200151600381111561648557fe5b614d2a565b915050616aeb565b600084111561653457838160600181815250506164c160405180602001604052808360400151815250856141e4565b8260200183608001828152508260038111156164d957fe5b60038111156164e457fe5b8152505050600060038111156164f657fe5b8160200151600381111561650657fe5b1461652f57616527600960298360200151600381111561652257fe5b614d2a565b915050616aeb565b6165c9565b6165508360405180602001604052808460400151815250618339565b82602001836060018281525082600381111561656857fe5b600381111561657357fe5b81525050506000600381111561658557fe5b8160200151600381111561659557fe5b146165be576165b66009602a836020015160038111156165b157fe5b614d2a565b915050616aeb565b828160800181815250505b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663eabe7d91308885606001516040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156166ac57600080fd5b505af11580156166c0573d6000803e3d6000fd5b505050506040513d60208110156166d657600080fd5b8101908080519060200190929190505050905060008114616707576166fe6003602883614d2a565b92505050616aeb565b61670f6148d2565b6009541461672c57616723600a602c614439565b92505050616aeb565b61673c600d548360600151614c81565b836020018460a0018281525082600381111561675457fe5b600381111561675f57fe5b81525050506000600381111561677157fe5b8260200151600381111561678157fe5b146167ab576167a26009602e8460200151600381111561679d57fe5b614d2a565b92505050616aeb565b6167f8600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548360600151614c81565b836020018460c0018281525082600381111561681057fe5b600381111561681b57fe5b81525050506000600381111561682d57fe5b8260200151600381111561683d57fe5b146168675761685e6009602d8460200151600381111561685957fe5b614d2a565b92505050616aeb565b8160800151616874614247565b101561688f57616886600e602f614439565b92505050616aeb565b61689d868360800151616241565b8160a00151600d819055508160c00151600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84606001516040518082815260200191505060405180910390a37fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9298683608001518460600151604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a1600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166351dff9893088856080015186606001516040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b158015616ac157600080fd5b505af1158015616ad5573d6000803e3d6000fd5b5050505060006010811115616ae657fe5b925050505b9392505050565b6000806000841415616b0d5760008080905091509150616b3e565b6000838502905083858281616b1e57fe5b0414616b3557600260008090509250925050616b3e565b60008192509250505b9250929050565b6000806000831415616b61576001600080905091509150616b72565b6000838581616b6c57fe5b04915091505b9250929050565b6000806000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634ef4c3e13087876040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015616c5b57600080fd5b505af1158015616c6f573d6000803e3d6000fd5b505050506040513d6020811015616c8557600080fd5b8101908080519060200190929190505050905060008114616cbc57616cad6003601f83614d2a565b6000809050925092505061713b565b616cc46148d2565b60095414616ce757616cd8600a6022614439565b6000809050925092505061713b565b616cef618884565b616cf7613a4a565b826020018360400182815250826003811115616d0f57fe5b6003811115616d1a57fe5b815250505060006003811115616d2c57fe5b81602001516003811115616d3c57fe5b14616d6d57616d5d6009602183602001516003811115616d5857fe5b614d2a565b600080905093509350505061713b565b616d778686617f5b565b8160c0018181525050616da08160c0015160405180602001604052808460400151815250618339565b826020018360600182815250826003811115616db857fe5b6003811115616dc357fe5b815250505060006003811115616dd557fe5b81602001516003811115616de557fe5b14616e58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4d494e545f45584348414e47455f43414c43554c4154494f4e5f4641494c454481525060200191505060405180910390fd5b616e68600d548260600151614d9e565b826020018360800182815250826003811115616e8057fe5b6003811115616e8b57fe5b815250505060006003811115616e9d57fe5b81602001516003811115616ead57fe5b14616f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180618b5d6028913960400191505060405180910390fd5b616f50600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548260600151614d9e565b826020018360a00182815250826003811115616f6857fe5b6003811115616f7357fe5b815250505060006003811115616f8557fe5b81602001516003811115616f9557fe5b14616feb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180618a28602b913960400191505060405180910390fd5b8060800151600d819055508060a00151600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f868260c001518360600151604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a18573ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83606001516040518082815260200191505060405180910390a36000601081111561712f57fe5b8160c001519350935050505b9250929050565b6000670de0b6b3a764000061715b84846000015161839c565b8161716257fe5b04905092915050565b60006171ad83836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f7700000000000000000000008152506183e6565b905092915050565b60006171bf6186ec565b6171c984846184a0565b90506171d4816160d5565b91505092915050565b600061721f83836040518060400160405280601181526020017f6164646974696f6e206f766572666c6f770000000000000000000000000000008152506184cc565b905092915050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663da3d454c3086866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561730757600080fd5b505af115801561731b573d6000803e3d6000fd5b505050506040513d602081101561733157600080fd5b8101908080519060200190929190505050905060008114617361576173596003600e83614d2a565b91505061765d565b6173696148d2565b600954146173845761737c600a80614439565b91505061765d565b8261738d614247565b10156173a75761739f600e6009614439565b91505061765d565b6173af6188d7565b6173b8856147c7565b8260000183602001828152508260038111156173d057fe5b60038111156173db57fe5b8152505050600060038111156173ed57fe5b816000015160038111156173fd57fe5b146174275761741e600960078360000151600381111561741957fe5b614d2a565b9250505061765d565b617435816020015185614d9e565b82600001836040018281525082600381111561744d57fe5b600381111561745857fe5b81525050506000600381111561746a57fe5b8160000151600381111561747a57fe5b146174a45761749b6009600c8360000151600381111561749657fe5b614d2a565b9250505061765d565b6174b0600b5485614d9e565b8260000183606001828152508260038111156174c857fe5b60038111156174d357fe5b8152505050600060038111156174e557fe5b816000015160038111156174f557fe5b1461751f576175166009600b8360000151600381111561751157fe5b614d2a565b9250505061765d565b6175298585616241565b8060400151601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600a54601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055508060600151600b819055507f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80858583604001518460600151604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182815260200194505050505060405180910390a16000601081111561765857fe5b925050505b92915050565b6000806000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fc7e71e30868a8a8a6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200195505050505050602060405180830381600087803b1580156177ad57600080fd5b505af11580156177c1573d6000803e3d6000fd5b505050506040513d60208110156177d757600080fd5b810190808051906020019092919050505090506000811461780e576177ff6003601283614d2a565b60008090509250925050617f52565b6178166148d2565b600954146178395761782a600a6016614439565b60008090509250925050617f52565b6178416148d2565b8473ffffffffffffffffffffffffffffffffffffffff16636c540baf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561788757600080fd5b505afa15801561789b573d6000803e3d6000fd5b505050506040513d60208110156178b157600080fd5b8101908080519060200190929190505050146178e2576178d3600a6011614439565b60008090509250925050617f52565b8673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156179315761792260066017614439565b60008090509250925050617f52565b60008514156179555761794660076015614439565b60008090509250925050617f52565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8514156179985761798960076014614439565b60008090509250925050617f52565b6000806179a6898989615a00565b91509150600060108111156179b757fe5b82146179e4576179d38260108111156179cc57fe5b6018614439565b600080905094509450505050617f52565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c488847b308a866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604080518083038186803b158015617ac157600080fd5b505afa158015617ad5573d6000803e3d6000fd5b505050506040513d6040811015617aeb57600080fd5b8101908080519060200190929190805190602001909291905050509150915060006010811115617b1757fe5b8214617b6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180618af56033913960400191505060405180910390fd5b808873ffffffffffffffffffffffffffffffffffffffff166370a082318c6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015617bec57600080fd5b505afa158015617c00573d6000803e3d6000fd5b505050506040513d6020811015617c1657600080fd5b81019080805190602001909291905050501015617c9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f4c49515549444154455f5345495a455f544f4f5f4d554348000000000000000081525060200191505060405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff161415617ce457617cdd308d8d85614e3b565b9050617ddd565b8873ffffffffffffffffffffffffffffffffffffffff1663b2a02ff18d8d856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015617d9f57600080fd5b505af1158015617db3573d6000803e3d6000fd5b505050506040513d6020811015617dc957600080fd5b810190808051906020019092919050505090505b60006010811115617dea57fe5b8114617e5e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f746f6b656e207365697a757265206661696c656400000000000000000000000081525060200191505060405180910390fd5b7f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb528c8c868c86604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019550505050505060405180910390a160006010811115617f4657fe5b84975097505050505050505b94509492505050565b600080601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561802457600080fd5b505afa158015618038573d6000803e3d6000fd5b505050506040513d602081101561804e57600080fd5b810190808051906020019092919050505090508173ffffffffffffffffffffffffffffffffffffffff166323b872dd8630876040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561811c57600080fd5b505af1158015618130573d6000803e3d6000fd5b5050505060003d6000811461814c576020811461815657600080fd5b6000199150618162565b60206000803e60005191505b50806181d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f544f4b454e5f5452414e534645525f494e5f4641494c4544000000000000000081525060200191505060405180910390fd5b6000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561827757600080fd5b505afa15801561828b573d6000803e3d6000fd5b505050506040513d60208110156182a157600080fd5b810190808051906020019092919050505090508281101561832a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f544f4b454e5f5452414e534645525f494e5f4f564552464c4f5700000000000081525060200191505060405180910390fd5b82810394505050505092915050565b60008060006183466186ec565b618350868661858b565b915091506000600381111561836157fe5b82600381111561836d57fe5b1461838357816000809050935093505050618395565b600061838e826160d5565b9350935050505b9250929050565b60006183de83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250618607565b905092915050565b6000838311158290618493576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561845857808201518184015260208101905061843d565b50505050905090810190601f1680156184855780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b6184a86186ec565b60405180602001604052806184c185600001518561839c565b815250905092915050565b600080838501905084811015839061857f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015618544578082015181840152602081019050618529565b50505050905090810190601f1680156185715780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50809150509392505050565b60006185956186ec565b6000806185aa670de0b6b3a764000087616af2565b91509150600060038111156185bb57fe5b8260038111156185c757fe5b146185eb578160405180602001604052806000815250809050935093505050618600565b6185f9818660000151616001565b9350935050505b9250929050565b6000808414806186175750600083145b1561862557600090506186e5565b600083850290508385828161863657fe5b041483906186df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156186a4578082015181840152602081019050618689565b50505050905090810190601f1680156186d15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50809150505b9392505050565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061874057805160ff191683800117855561876e565b8280016001018555821561876e579182015b8281111561876d578251825591602001919060010190618752565b5b50905061877b919061890a565b5090565b6040518061012001604052806000600381111561879857fe5b815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806101000160405280600060108111156187ef57fe5b81526020016000600381111561880157fe5b81526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060e001604052806000601081111561884957fe5b81526020016000600381111561885b57fe5b815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060e001604052806000601081111561889c57fe5b8152602001600060038111156188ae57fe5b815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060800160405280600060038111156188ef57fe5b81526020016000815260200160008152602001600081525090565b61892c91905b80821115618928576000816000905550600101618910565b5090565b9056fe6f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e63654345726332303a3a7377656570546f6b656e3a2063616e206e6f7420737765657020756e6465726c79696e6720746f6b656e696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e6f6e6c79207468652061646d696e206d6179207365742074686520636f6d702d6c696b652064656c656761746573657474696e6720696e7465726573742072617465206d6f64656c206661696c65644d494e545f4e45575f4143434f554e545f42414c414e43455f43414c43554c4154494f4e5f4641494c4544626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e636553746f726564496e7465726e616c206661696c656452455041595f424f52524f575f4e45575f4143434f554e545f424f52524f575f42414c414e43455f43414c43554c4154494f4e5f4641494c454452455041595f424f52524f575f4e45575f544f54414c5f42414c414e43455f43414c43554c4154494f4e5f4641494c45444c49515549444154455f434f4d5054524f4c4c45525f43414c43554c4154455f414d4f554e545f5345495a455f4641494c454465786368616e67655261746553746f7265643a2065786368616e67655261746553746f726564496e7465726e616c206661696c65644d494e545f4e45575f544f54414c5f535550504c595f43414c43554c4154494f4e5f4641494c45446f6e65206f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e206d757374206265207a65726f72656475636520726573657276657320756e657870656374656420756e646572666c6f77a265627a7a72315820ba68e2fa7a2baaf6e98f64c05eddd43137feaefb30b51b0ce823cf1632ec545664736f6c63430005110032 \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/CUSDC.sol b/benchmark/ethereum/compound/contract/CUSDC.sol new file mode 100644 index 0000000..ddf625b --- /dev/null +++ b/benchmark/ethereum/compound/contract/CUSDC.sol @@ -0,0 +1,222 @@ +pragma solidity ^0.5.16; + +import "./CToken.sol"; + +interface CompLike { + function delegate(address delegatee) external; +} + +/** + * @title Compound's CErc20 Contract + * @notice CTokens which wrap an EIP-20 underlying + * @author Compound + */ +contract CErc20 is CToken, CErc20Interface { + /** + * @notice Initialize the new money market + * @param underlying_ The address of the underlying asset + * @param comptroller_ The address of the Comptroller + * @param interestRateModel_ The address of the interest rate model + * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 + * @param name_ ERC-20 name of this token + * @param symbol_ ERC-20 symbol of this token + * @param decimals_ ERC-20 decimal precision of this token + */ + function initialize(address underlying_, + ComptrollerInterface comptroller_, + InterestRateModel interestRateModel_, + uint initialExchangeRateMantissa_, + string memory name_, + string memory symbol_, + uint8 decimals_) public { + // CToken initialize does the bulk of the work + super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_); + + // Set underlying and sanity check it + underlying = underlying_; + EIP20Interface(underlying).totalSupply(); + } + + /*** User Interface ***/ + + /** + * @notice Sender supplies assets into the market and receives cTokens in exchange + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param mintAmount The amount of the underlying asset to supply + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function mint(uint mintAmount) external returns (uint) { + (uint err,) = mintInternal(mintAmount); + return err; + } + + /** + * @notice Sender redeems cTokens in exchange for the underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemTokens The number of cTokens to redeem into underlying + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function redeem(uint redeemTokens) external returns (uint) { + return redeemInternal(redeemTokens); + } + + /** + * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemAmount The amount of underlying to redeem + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function redeemUnderlying(uint redeemAmount) external returns (uint) { + return redeemUnderlyingInternal(redeemAmount); + } + + /** + * @notice Sender borrows assets from the protocol to their own address + * @param borrowAmount The amount of the underlying asset to borrow + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function borrow(uint borrowAmount) external returns (uint) { + return borrowInternal(borrowAmount); + } + + /** + * @notice Sender repays their own borrow + * @param repayAmount The amount to repay + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function repayBorrow(uint repayAmount) external returns (uint) { + (uint err,) = repayBorrowInternal(repayAmount); + return err; + } + + /** + * @notice Sender repays a borrow belonging to borrower + * @param borrower the account with the debt being payed off + * @param repayAmount The amount to repay + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) { + (uint err,) = repayBorrowBehalfInternal(borrower, repayAmount); + return err; + } + + /** + * @notice The sender liquidates the borrowers collateral. + * The collateral seized is transferred to the liquidator. + * @param borrower The borrower of this cToken to be liquidated + * @param repayAmount The amount of the underlying borrowed asset to repay + * @param cTokenCollateral The market in which to seize collateral from the borrower + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) external returns (uint) { + (uint err,) = liquidateBorrowInternal(borrower, repayAmount, cTokenCollateral); + return err; + } + + /** + * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock) + * @param token The address of the ERC-20 token to sweep + */ + function sweepToken(EIP20NonStandardInterface token) external { + require(address(token) != underlying, "CErc20::sweepToken: can not sweep underlying token"); + uint256 balance = token.balanceOf(address(this)); + token.transfer(admin, balance); + } + + /** + * @notice The sender adds to reserves. + * @param addAmount The amount fo underlying token to add as reserves + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function _addReserves(uint addAmount) external returns (uint) { + return _addReservesInternal(addAmount); + } + + /*** Safe Token ***/ + + /** + * @notice Gets balance of this contract in terms of the underlying + * @dev This excludes the value of the current message, if any + * @return The quantity of underlying tokens owned by this contract + */ + function getCashPrior() internal view returns (uint) { + EIP20Interface token = EIP20Interface(underlying); + return token.balanceOf(address(this)); + } + + /** + * @dev Similar to EIP20 transfer, except it handles a False result from `transferFrom` and reverts in that case. + * This will revert due to insufficient balance or insufficient allowance. + * This function returns the actual amount received, + * which may be less than `amount` if there is a fee attached to the transfer. + * + * Note: This wrapper safely handles non-standard ERC-20 tokens that do not return a value. + * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca + */ + function doTransferIn(address from, uint amount) internal returns (uint) { + EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying); + uint balanceBefore = EIP20Interface(underlying).balanceOf(address(this)); + token.transferFrom(from, address(this), amount); + + bool success; + assembly { + switch returndatasize() + case 0 { // This is a non-standard ERC-20 + success := not(0) // set success to true + } + case 32 { // This is a compliant ERC-20 + returndatacopy(0, 0, 32) + success := mload(0) // Set `success = returndata` of external call + } + default { // This is an excessively non-compliant ERC-20, revert. + revert(0, 0) + } + } + require(success, "TOKEN_TRANSFER_IN_FAILED"); + + // Calculate the amount that was *actually* transferred + uint balanceAfter = EIP20Interface(underlying).balanceOf(address(this)); + require(balanceAfter >= balanceBefore, "TOKEN_TRANSFER_IN_OVERFLOW"); + return balanceAfter - balanceBefore; // underflow already checked above, just subtract + } + + /** + * @dev Similar to EIP20 transfer, except it handles a False success from `transfer` and returns an explanatory + * error code rather than reverting. If caller has not called checked protocol's balance, this may revert due to + * insufficient cash held in this contract. If caller has checked protocol's balance prior to this call, and verified + * it is >= amount, this should not revert in normal conditions. + * + * Note: This wrapper safely handles non-standard ERC-20 tokens that do not return a value. + * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca + */ + function doTransferOut(address payable to, uint amount) internal { + EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying); + token.transfer(to, amount); + + bool success; + assembly { + switch returndatasize() + case 0 { // This is a non-standard ERC-20 + success := not(0) // set success to true + } + case 32 { // This is a compliant ERC-20 + returndatacopy(0, 0, 32) + success := mload(0) // Set `success = returndata` of external call + } + default { // This is an excessively non-compliant ERC-20, revert. + revert(0, 0) + } + } + require(success, "TOKEN_TRANSFER_OUT_FAILED"); + } + + /** + * @notice Admin call to delegate the votes of the COMP-like underlying + * @param compLikeDelegatee The address to delegate votes to + * @dev CTokens whose underlying are not CompLike should revert here + */ + function _delegateCompLikeTo(address compLikeDelegatee) external { + require(msg.sender == admin, "only the admin may set the comp-like delegate"); + CompLike(underlying).delegate(compLikeDelegatee); + } +} diff --git a/benchmark/ethereum/compound/contract/Comptroller.abi b/benchmark/ethereum/compound/contract/Comptroller.abi new file mode 100644 index 0000000..db6e292 --- /dev/null +++ b/benchmark/ethereum/compound/contract/Comptroller.abi @@ -0,0 +1,2221 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "CompGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorCompSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerComp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierComp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "_borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "_grantComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "_setBorrowCapGuardian", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setBorrowPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "_setCompSpeeds", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setContributorCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setMintPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setSeizePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setTransferPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "_upgradeSplitCompRewards", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "compInitialIndex", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "compRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddr", + "type": "address" + } + ], + "name": "enterOneMarkets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getCompAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "isDeprecated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "maxAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "mintVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract PriceOracle", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowerIndex", + "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/Comptroller.bin b/benchmark/ethereum/compound/contract/Comptroller.bin new file mode 100644 index 0000000..fe2e3e7 --- /dev/null +++ b/benchmark/ethereum/compound/contract/Comptroller.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061a1f280620000626000396000f3fe608060405234801561001057600080fd5b506004361061047f5760003560e01c8063741b252511610257578063b30d442711610146578063dce15449116100c3578063e9af029211610087578063e9af0292146124b2578063eabe7d91146124f6578063ede4edd014612578578063f4a433c0146125d0578063f851a440146126285761047f565b8063dce1544914612338578063dcfbc0c7146123c6578063e4028eee14612410578063e6653f3d14612472578063e8755446146124945761047f565b8063c488847b1161010a578063c488847b1461209b578063ca0af04314612124578063cc7ebdc41461219c578063d02f7351146121f4578063da3d454c146122b65761047f565b8063b30d442714611e40578063bb82aa5e14611e4a578063bdcdc25814611e94578063bea6b8b814611f36578063c299823814611f8e5761047f565b8063986ab838116101d4578063aa90075411610198578063aa90075414611c90578063abfceffc14611cae578063ac0b0bb714611d47578063b0772d0b14611d69578063b21be7fd14611dc85761047f565b8063986ab8381461195c5780639d1b5a0a146119b4578063a76b3fda146119fe578063a7f0e23114611a56578063a8b4394814611ab05761047f565b80638e8f294b1161021b5780638e8f294b146117b05780638ebf63641461181e578063929fe9a11461186657806394543c15146118e257806394b2294b1461193e5761047f565b8063741b2525146116015780637dc0d1d01461164557806387495bad1461168f57806387f76303146116e75780638c57804e146117095761047f565b80634ada90af116103735780635f5af1aa116102f05780636aa875b5116102b45780636aa875b51461139c5780636b79c38d146113f45780636d154ea51461149b5780636d35bf91146114f7578063731f0c2b146115a55761047f565b80635f5af1aa14610fc25780635fc7e71e1461101a578063607ef6c1146110dc5780636810dfa6146111aa5780636a56947e1461130e5761047f565b806352d84d1e1161033757806352d84d1e14610dda57806355ee1fe114610e48578063598ee1cb14610ea05780635c77860514610eee5780635ec88c7914610f5c5761047f565b80634ada90af14610be65780634e79238f14610c045780634ef4c3e114610c9e5780634fd42e1714610d2057806351dff98914610d625761047f565b806327efe3cb116104015780633c94786f116103c55780633c94786f14610a1e57806341c728b914610a4057806342cbb15c14610ab857806347ef3b3b14610ad65780634a58443214610b8e5761047f565b806327efe3cb1461089a5780632d70db78146108e8578063317b0b7714610930578063391957d7146109725780633bcf7ec1146109b65761047f565b80631ededc91116104485780631ededc911461068257806321af45691461071a57806324008a621461076457806324a3d6221461080657806326782247146108505761047f565b80627e3dd21461048457806318c882a5146104a65780631c3db2e01461050e5780631d504dc6146105e65780631d7b33d71461062a575b600080fd5b61048c612672565b604051808215151515815260200191505060405180910390f35b6104f4600480360360408110156104bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612677565b604051808215151515815260200191505060405180910390f35b6105e46004803603604081101561052457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561056157600080fd5b82018360208201111561057357600080fd5b8035906020019184602083028401116401000000008311171561059557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506129f4565b005b610628600480360360208110156105fc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a83565b005b61066c6004803603602081101561064057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ce2565b6040518082815260200191505060405180910390f35b610718600480360360a081101561069857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050612cfa565b005b610722612d12565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107f06004803603608081101561077a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612d38565b6040518082815260200191505060405180910390f35b61080e612e69565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610858612e8f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108e6600480360360408110156108b057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612eb5565b005b610916600480360360208110156108fe57600080fd5b81019080803515159060200190929190505050613023565b604051808215151515815260200191505060405180910390f35b61095c6004803603602081101561094657600080fd5b8101908080359060200190929190505050613289565b6040518082815260200191505060405180910390f35b6109b46004803603602081101561098857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506133b1565b005b610a04600480360360408110156109cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050613559565b604051808215151515815260200191505060405180910390f35b610a266138d6565b604051808215151515815260200191505060405180910390f35b610ab660048036036080811015610a5657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506138e9565b005b610ac0613900565b6040518082815260200191505060405180910390f35b610b8c600480360360c0811015610aec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050613908565b005b610bd060048036036020811015610ba457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613921565b6040518082815260200191505060405180910390f35b610bee613939565b6040518082815260200191505060405180910390f35b610c7a60048036036080811015610c1a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061393f565b60405180848152602001838152602001828152602001935050505060405180910390f35b610d0a60048036036060811015610cb457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061397b565b6040518082815260200191505060405180910390f35b610d4c60048036036020811015610d3657600080fd5b8101908080359060200190929190505050613acf565b6040518082815260200191505060405180910390f35b610dd860048036036080811015610d7857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050613b9b565b005b610e0660048036036020811015610df057600080fd5b8101908080359060200190929190505050613c24565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610e8a60048036036020811015610e5e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c60565b6040518082815260200191505060405180910390f35b610eec60048036036040811015610eb657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613dde565b005b610f5a60048036036060811015610f0457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613f94565b005b610f9e60048036036020811015610f7257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613faa565b60405180848152602001838152602001828152602001935050505060405180910390f35b61100460048036036020811015610fd857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613fe5565b6040518082815260200191505060405180910390f35b6110c6600480360360a081101561103057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614185565b6040518082815260200191505060405180910390f35b6111a8600480360360408110156110f257600080fd5b810190808035906020019064010000000081111561110f57600080fd5b82018360208201111561112157600080fd5b8035906020019184602083028401116401000000008311171561114357600080fd5b90919293919293908035906020019064010000000081111561116457600080fd5b82018360208201111561117657600080fd5b8035906020019184602083028401116401000000008311171561119857600080fd5b9091929391929390505050614431565b005b61130c600480360360808110156111c057600080fd5b81019080803590602001906401000000008111156111dd57600080fd5b8201836020820111156111ef57600080fd5b8035906020019184602083028401116401000000008311171561121157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561127157600080fd5b82018360208201111561128357600080fd5b803590602001918460208302840111640100000000831117156112a557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035151590602001909291908035151590602001909291905050506146ea565b005b61139a6004803603608081101561132457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614a08565b005b6113de600480360360208110156113b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614a1f565b6040518082815260200191505060405180910390f35b6114366004803603602081101561140a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614a37565b60405180837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390f35b6114dd600480360360208110156114b157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614a93565b604051808215151515815260200191505060405180910390f35b6115a3600480360360a081101561150d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614ab3565b005b6115e7600480360360208110156115bb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614acb565b604051808215151515815260200191505060405180910390f35b6116436004803603602081101561161757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614aeb565b005b61164d614c89565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6116d1600480360360208110156116a557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614caf565b6040518082815260200191505060405180910390f35b6116ef614cd2565b604051808215151515815260200191505060405180910390f35b61174b6004803603602081101561171f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614ce5565b60405180837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390f35b6117f2600480360360208110156117c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614d41565b604051808415151515815260200183815260200182151515158152602001935050505060405180910390f35b61184c6004803603602081101561183457600080fd5b81019080803515159060200190929190505050614d85565b604051808215151515815260200191505060405180910390f35b6118c86004803603604081101561187c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614feb565b604051808215151515815260200191505060405180910390f35b611924600480360360208110156118f857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615082565b604051808215151515815260200191505060405180910390f35b6119466151bf565b6040518082815260200191505060405180910390f35b61199e6004803603602081101561197257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506151c5565b6040518082815260200191505060405180910390f35b6119bc6151dd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611a4060048036036020811015611a1457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506151f9565b6040518082815260200191505060405180910390f35b611a5e615484565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611c8e60048036036060811015611ac657600080fd5b8101908080359060200190640100000000811115611ae357600080fd5b820183602082011115611af557600080fd5b80359060200191846020830284011164010000000083111715611b1757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115611b7757600080fd5b820183602082011115611b8957600080fd5b80359060200191846020830284011164010000000083111715611bab57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115611c0b57600080fd5b820183602082011115611c1d57600080fd5b80359060200191846020830284011164010000000083111715611c3f57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050615497565b005b611c986155e0565b6040518082815260200191505060405180910390f35b611cf060048036036020811015611cc457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506155e6565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015611d33578082015181840152602081019050611d18565b505050509050019250505060405180910390f35b611d4f6156b8565b604051808215151515815260200191505060405180910390f35b611d716156cb565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015611db4578082015181840152602081019050611d99565b505050509050019250505060405180910390f35b611e2a60048036036040811015611dde57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615759565b6040518082815260200191505060405180910390f35b611e4861577e565b005b611e52615d3b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611f2060048036036080811015611eaa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050615d61565b6040518082815260200191505060405180910390f35b611f7860048036036020811015611f4c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615e47565b6040518082815260200191505060405180910390f35b61204460048036036020811015611fa457600080fd5b8101908080359060200190640100000000811115611fc157600080fd5b820183602082011115611fd357600080fd5b80359060200191846020830284011164010000000083111715611ff557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050615e5f565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561208757808201518184015260208101905061206c565b505050509050019250505060405180910390f35b612107600480360360608110156120b157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050615f07565b604051808381526020018281526020019250505060405180910390f35b6121866004803603604081101561213a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616222565b6040518082815260200191505060405180910390f35b6121de600480360360208110156121b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616247565b6040518082815260200191505060405180910390f35b6122a0600480360360a081101561220a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061625f565b6040518082815260200191505060405180910390f35b612322600480360360608110156122cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050616523565b6040518082815260200191505060405180910390f35b6123846004803603604081101561234e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050616bd3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6123ce616c1e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61245c6004803603604081101561242657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050616c44565b6040518082815260200191505060405180910390f35b61247a616f1d565b604051808215151515815260200191505060405180910390f35b61249c616f30565b6040518082815260200191505060405180910390f35b6124f4600480360360208110156124c857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616f36565b005b6125626004803603606081101561250c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050616fc9565b6040518082815260200191505060405180910390f35b6125ba6004803603602081101561258e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050617020565b6040518082815260200191505060405180910390f35b612612600480360360208110156125e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050617598565b6040518082815260200191505060405180910390f35b6126306175b0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600181565b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1661271e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061a0776028913960400191505060405180910390fd5b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806127c657506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61281b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061a0c76027913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061287a575060011515821515145b6128ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792061646d696e2063616e20756e70617573650000000000000000000081525060200191505060405180910390fd5b81600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b08383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200183151515158152602001828103825260068152602001807f426f72726f770000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a181905092915050565b60606001604051908082528060200260200182016040528015612a265781602001602082028038833980820191505090505b5090508281600081518110612a3757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050612a7e81836001806146ea565b505050565b8073ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612ac957600080fd5b505afa158015612add573d6000803e3d6000fd5b505050506040513d6020811015612af357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061a1976027913960400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1663c1e803346040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612bd157600080fd5b505af1158015612be5573d6000803e3d6000fd5b505050506040513d6020811015612bfb57600080fd5b810190808051906020019092919050505014612c7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6368616e6765206e6f7420617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663b30d44276040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612cc757600080fd5b505af1158015612cdb573d6000803e3d6000fd5b5050505050565b600f6020528060005260406000206000915090505481565b600015612d0b576007546007819055505b5050505050565b601560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16612da25760096011811115612d9b57fe5b9050612e61565b612daa619f81565b60405180602001604052808773ffffffffffffffffffffffffffffffffffffffff1663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612dfb57600080fd5b505afa158015612e0f573d6000803e3d6000fd5b505050506040513d6020811015612e2557600080fd5b81019080805190602001909291905050508152509050612e4586826175d5565b612e5086858361790e565b60006011811115612e5d57fe5b9150505b949350505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612ebd617d13565b612f2f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f6f6e6c792061646d696e2063616e206772616e7420636f6d700000000000000081525060200191505060405180910390fd5b6000612f3b8383617dc2565b905060008114612fb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f696e73756666696369656e7420636f6d7020666f72206772616e74000000000081525060200191505060405180910390fd5b7f98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c8383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806130cd57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b613122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061a0c76027913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480613181575060011515821515145b6131f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792061646d696e2063616e20756e70617573650000000000000000000081525060200191505060405180910390fd5b81600a60176101000a81548160ff0219169083151502179055507fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de082604051808060200183151515158152602001828103825260058152602001807f5365697a650000000000000000000000000000000000000000000000000000008152506020019250505060405180910390a1819050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461334d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f720081525060200191505060405180910390fd5b60006005549050826005819055507f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd981600554604051808381526020018281526020019250505060405180910390a1600060118111156133a957fe5b915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613456576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061a0ee6026913960400191505060405180910390fd5b6000601560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081601560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e298183604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16613600576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061a0776028913960400191505060405180910390fd5b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806136a857506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6136fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061a0c76027913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061375c575060011515821515145b6137ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792061646d696e2063616e20756e70617573650000000000000000000081525060200191505060405180910390fd5b81600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b08383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200183151515158152602001828103825260048152602001807f4d696e7400000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a181905092915050565b600a60149054906101000a900460ff1681565b6000156138fa576007546007819055505b50505050565b600043905090565b600015613919576007546007819055505b505050505050565b60166020528060005260406000206000915090505481565b60065481565b6000806000806000806139548a8a8a8a617f7a565b92509250925082601181111561396657fe5b82829550955095505050509450945094915050565b6000600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615613a3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f6d696e742069732070617573656400000000000000000000000000000000000081525060200191505060405180910390fd5b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16613aa55760096011811115613a9e57fe5b9050613ac8565b613aae84618469565b613ab88484618798565b60006011811115613ac557fe5b90505b9392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613b3857613b316001600b618b93565b9050613b96565b60006006549050826006819055507faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec13168184604051808381526020018281526020019250505060405180910390a160006011811115613b9257fe5b9150505b919050565b600081148015613bab5750600082115b15613c1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f72656465656d546f6b656e73207a65726f00000000000000000000000000000081525060200191505060405180910390fd5b50505050565b600d8181548110613c3157fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613cc957613cc260016010618b93565b9050613dd9565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e228184604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a160006011811115613dd557fe5b9150505b919050565b613de6617d13565b613e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f6e6c792061646d696e2063616e2073657420636f6d7020737065656400000081525060200191505060405180910390fd5b613e6182614aeb565b6000811415613eb257601860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009055613efe565b613eba613900565b601860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b80601760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff167f386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b3826040518082815260200191505060405180910390a25050565b600015613fa5576007546007819055505b505050565b600080600080600080613fc1876000806000617f7a565b925092509250826011811115613fd357fe5b82829550955095505050509193909250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461404e5761404760016013618b93565b9050614180565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e81600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a16000601181111561417c57fe5b9150505b919050565b6000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615806142305750600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16155b15614249576009601181111561424257fe5b9050614428565b60008673ffffffffffffffffffffffffffffffffffffffff166395dd9193856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156142c857600080fd5b505afa1580156142dc573d6000803e3d6000fd5b505050506040513d60208110156142f257600080fd5b8101908080519060200190929190505050905061430e87615082565b15614371578281101561436c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061a09f6028913960400191505060405180910390fd5b614417565b60008061437d86618c07565b92505091506000601181111561438f57fe5b82601181111561439b57fe5b146143b6578160118111156143ac57fe5b9350505050614428565b60008114156143d657600360118111156143cc57fe5b9350505050614428565b60006143f2604051806020016040528060055481525085618c27565b9050808611156144135760118081111561440857fe5b945050505050614428565b5050505b6000601181111561442457fe5b9150505b95945050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806144d95750601560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61452e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603581526020018061a1146035913960400191505060405180910390fd5b600084849050905060008383905090506000821415801561454e57508082145b6145c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f696e76616c696420696e7075740000000000000000000000000000000000000081525060200191505060405180910390fd5b60008090505b828110156146e1578484828181106145da57fe5b90506020020135601660008989858181106145f157fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555086868281811061465857fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f68686848181106146b857fe5b905060200201356040518082815260200191505060405180910390a280806001019150506145c6565b50505050505050565b60008090505b835181101561491f57600084828151811061470757fe5b60200260200101519050600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff166147d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6d61726b6574206d757374206265206c6973746564000000000000000000000081525060200191505060405180910390fd5b6001151584151514156148c0576147e8619f81565b60405180602001604052808373ffffffffffffffffffffffffffffffffffffffff1663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561483957600080fd5b505afa15801561484d573d6000803e3d6000fd5b505050506040513d602081101561486357600080fd5b8101908080519060200190929190505050815250905061488382826175d5565b60008090505b87518110156148bd576148b0838983815181106148a257fe5b60200260200101518461790e565b8080600101915050614889565b50505b600115158315151415614911576148d681618469565b60008090505b865181101561490f57614902828883815181106148f557fe5b6020026020010151618798565b80806001019150506148dc565b505b5080806001019150506146f0565b5060008090505b8451811015614a015761499e85828151811061493e57fe5b60200260200101516014600088858151811061495657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054617dc2565b601460008784815181106149ae57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508080600101915050614926565b5050505050565b600015614a19576007546007819055505b50505050565b601a6020528060005260406000206000915090505481565b60106020528060005260406000206000915090508060000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169080600001601c9054906101000a900463ffffffff16905082565b600c6020528060005260406000206000915054906101000a900460ff1681565b600015614ac4576007546007819055505b5050505050565b600b6020528060005260406000206000915054906101000a900460ff1681565b6000601760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000614b39613900565b90506000614b8682601860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054618c4f565b9050600081118015614b985750600083115b15614c83576000614ba98285618c99565b90506000614bf6601460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483618ce3565b905080601460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555083601860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505b50505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080829050614cbf8133618d2d565b6011811115614cca57fe5b915050919050565b600a60169054906101000a900460ff1681565b60116020528060005260406000206000915090508060000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169080600001601c9054906101000a900463ffffffff16905082565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154908060030160009054906101000a900460ff16905083565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480614e2f57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b614e84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061a0c76027913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480614ee3575060011515821515145b614f55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792061646d696e2063616e20756e70617573650000000000000000000081525060200191505060405180910390fd5b81600a60166101000a81548160ff0219169083151502179055507fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de082604051808060200183151515158152602001828103825260088152602001807f5472616e736665720000000000000000000000000000000000000000000000008152506020019250505060405180910390a1819050919050565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600080600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154148015615125575060011515600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515145b80156151b85750670de0b6b3a76400008273ffffffffffffffffffffffffffffffffffffffff1663173b99046040518163ffffffff1660e01b815260040160206040518083038186803b15801561517b57600080fd5b505afa15801561518f573d6000803e3d6000fd5b505050506040513d60208110156151a557600080fd5b8101908080519060200190929190505050145b9050919050565b60075481565b60176020528060005260406000206000915090505481565b600073c00e94cb662c3520282e6f5717214004a7f26888905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146152625761525b60016012618b93565b905061547f565b600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16156152ca576152c3600a6011618b93565b905061547f565b8173ffffffffffffffffffffffffffffffffffffffff1663fe9c44ae6040518163ffffffff1660e01b815260040160206040518083038186803b15801561531057600080fd5b505afa158015615324573d6000803e3d6000fd5b505050506040513d602081101561533a57600080fd5b81019080805190602001909291905050505060405180606001604052806001151581526020016000815260200160001515815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160030160006101000a81548160ff02191690831515021790555090505061540382618f96565b61540c826190f9565b7fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16000601181111561547c57fe5b90505b919050565b6ec097ce7bc90715b34b9f100000000081565b61549f617d13565b615511576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f6e6c792061646d696e2063616e2073657420636f6d7020737065656400000081525060200191505060405180910390fd5b6000835190508251811480156155275750815181145b61557c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061a16e6029913960400191505060405180910390fd5b60008090505b818110156155d9576155ce85828151811061559957fe5b60200260200101518583815181106155ad57fe5b60200260200101518584815181106155c157fe5b602002602001015161937f565b806001019050615582565b5050505050565b600e5481565b606080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156156a857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161565e575b5050505050905080915050919050565b600a60179054906101000a900460ff1681565b6060600d80548060200260200160405190810160405280929190818152602001828054801561574f57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311615705575b5050505050905090565b6012602052816000526040600020602052806000526040600020600091509150505481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614615841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f6e6c7920627261696e732063616e206265636f6d6520697473656c6600000081525060200191505060405180910390fd5b600061588961584e613900565b6040518060400160405280601c81526020017f626c6f636b206e756d62657220657863656564732033322062697473000000008152506196ab565b905060008090505b600d80549050811015615d3757600f6000600d83815481106158af57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054601a6000600d848154811061592657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905560196000600d848154811061599f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600f6000600d8381548110615a1957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009055600060106000600d8481548110615a9557fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600060116000600d8581548110615b0f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008260000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161415615c4f576ec097ce7bc90715b34b9f10000000008260000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055508382600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505b60008160000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161415615d28576ec097ce7bc90715b34b9f10000000008160000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055508381600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505b50508080600101915050615891565b5050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60169054906101000a900460ff1615615de6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f7472616e7366657220697320706175736564000000000000000000000000000081525060200191505060405180910390fd5b6000615df3868685619766565b905060006011811115615e0257fe5b8114615e115780915050615e3f565b615e1a86618469565b615e248686618798565b615e2e8685618798565b60006011811115615e3b57fe5b9150505b949350505050565b60186020528060005260406000206000915090505481565b6060600082519050606081604051908082528060200260200182016040528015615e985781602001602082028038833980820191505090505b50905060008090505b82811015615efc576000858281518110615eb757fe5b60200260200101519050615ecb8133618d2d565b6011811115615ed657fe5b838381518110615ee257fe5b602002602001018181525050508080600101915050615ea1565b508092505050919050565b6000806000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc57d4df876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015615fab57600080fd5b505afa158015615fbf573d6000803e3d6000fd5b505050506040513d6020811015615fd557600080fd5b810190808051906020019092919050505090506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc57d4df876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561608957600080fd5b505afa15801561609d573d6000803e3d6000fd5b505050506040513d60208110156160b357600080fd5b8101908080519060200190929190505050905060008214806160d55750600081145b156160f757600d60118111156160e757fe5b600080905093509350505061621a565b60008673ffffffffffffffffffffffffffffffffffffffff1663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561613f57600080fd5b505afa158015616153573d6000803e3d6000fd5b505050506040513d602081101561616957600080fd5b810190808051906020019092919050505090506000616186619f81565b61618e619f81565b616196619f81565b6161be604051806020016040528060065481525060405180602001604052808a8152506198f5565b92506161e66040518060200160405280888152506040518060200160405280888152506198f5565b91506161f28383619936565b90506161fe818b618c27565b93506000601181111561620d57fe5b8498509850505050505050505b935093915050565b6013602052816000526040600020602052806000526040600020600091509150505481565b60146020528060005260406000206000915090505481565b6000600a60179054906101000a900460ff16156162e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f7365697a6520697320706175736564000000000000000000000000000000000081525060200191505060405180910390fd5b600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16158061638d5750600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16155b156163a6576009601181111561639f57fe5b905061651a565b8473ffffffffffffffffffffffffffffffffffffffff16635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156163ec57600080fd5b505afa158015616400573d6000803e3d6000fd5b505050506040513d602081101561641657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561648357600080fd5b505afa158015616497573d6000803e3d6000fd5b505050506040513d60208110156164ad57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16146164ed57600260118111156164e657fe5b905061651a565b6164f686618469565b6165008684618798565b61650a8685618798565b6000601181111561651757fe5b90505b95945050505050565b6000600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156165e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f626f72726f77206973207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1661664d576009601181111561664657fe5b9050616bcc565b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16616854578373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461677f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f73656e646572206d7573742062652063546f6b656e000000000000000000000081525060200191505060405180910390fd5b600061678b3385618d2d565b90506000601181111561679a57fe5b8160118111156167a657fe5b146167bf578060118111156167b757fe5b915050616bcc565b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661685257fe5b505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc57d4df866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156168f557600080fd5b505afa158015616909573d6000803e3d6000fd5b505050506040513d602081101561691f57600080fd5b8101908080519060200190929190505050141561694a57600d601181111561694357fe5b9050616bcc565b6000601660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114616aa15760008573ffffffffffffffffffffffffffffffffffffffff166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156169de57600080fd5b505afa1580156169f2573d6000803e3d6000fd5b505050506040513d6020811015616a0857600080fd5b810190808051906020019092919050505090506000616a278286618ce3565b9050828110616a9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f6d61726b657420626f72726f772063617020726561636865640000000000000081525060200191505060405180910390fd5b50505b600080616ab18688600088617f7a565b925050915060006011811115616ac357fe5b826011811115616acf57fe5b14616aea57816011811115616ae057fe5b9350505050616bcc565b6000811115616b0a5760046011811115616b0057fe5b9350505050616bcc565b616b12619f81565b60405180602001604052808973ffffffffffffffffffffffffffffffffffffffff1663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015616b6357600080fd5b505afa158015616b77573d6000803e3d6000fd5b505050506040513d6020811015616b8d57600080fd5b81019080805190602001909291905050508152509050616bad88826175d5565b616bb888888361790e565b60006011811115616bc557fe5b9450505050505b9392505050565b60086020528160005260406000208181548110616bec57fe5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614616cad57616ca660016006618b93565b9050616f17565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff16616d1a57616d1260096007618b93565b915050616f17565b616d22619f81565b6040518060200160405280858152509050616d3b619f81565b6040518060200160405280670c7d713b49da00008152509050616d5e8183619977565b15616d7957616d6f60066008618b93565b9350505050616f17565b60008514158015616e6357506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc57d4df886040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015616e2657600080fd5b505afa158015616e3a573d6000803e3d6000fd5b505050506040513d6020811015616e5057600080fd5b8101908080519060200190929190505050145b15616e7e57616e74600d6009618b93565b9350505050616f17565b6000836001015490508584600101819055507f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5878288604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a160006011811115616f1057fe5b9450505050505b92915050565b600a60159054906101000a900460ff1681565b60055481565b616fc681600d805480602002602001604051908101604052809291908181526020018280548015616fbc57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311616f72575b50505050506129f4565b50565b600080616fd7858585619766565b905060006011811115616fe657fe5b8114616ff55780915050617019565b616ffe85618469565b6170088585618798565b6000601181111561701557fe5b9150505b9392505050565b60008082905060008060008373ffffffffffffffffffffffffffffffffffffffff1663c37f68e2336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060806040518083038186803b1580156170a857600080fd5b505afa1580156170bc573d6000803e3d6000fd5b505050506040513d60808110156170d257600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291905050505092509250925060008314617161576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061a1496025913960400191505060405180910390fd5b6000811461718057617175600c6002618b93565b945050505050617593565b600061718d873385619766565b9050600081146171b0576171a4600e60038361998c565b95505050505050617593565b6000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16617260576000601181111561725357fe5b9650505050505050617593565b8060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff02191690556060600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561737257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311617328575b50505050509050600081519050600081905060008090505b828110156173ee578973ffffffffffffffffffffffffffffffffffffffff168482815181106173b557fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156173e1578091506173ee565b808060010191505061738a565b508181106173f857fe5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060018280549050038154811061744e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681838154811061748557fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808054809190600190036174e19190619f94565b507fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d8a33604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a16000601181111561758657fe5b9a50505050505050505050505b919050565b60196020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000601960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006176a4617669613900565b6040518060400160405280601c81526020017f626c6f636b206e756d62657220657863656564732033322062697473000000008152506196ab565b905060006176d28263ffffffff1685600001601c9054906101000a900463ffffffff1663ffffffff16618c4f565b90506000811180156176e45750600083115b156178d85760006177758773ffffffffffffffffffffffffffffffffffffffff166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561773457600080fd5b505afa158015617748573d6000803e3d6000fd5b505050506040513d602081101561775e57600080fd5b810190808051906020019092919050505087619a00565b905060006177838386618c99565b905061778d619fc0565b600083116177aa57604051806020016040528060008152506177b5565b6177b48284619a29565b5b905061785b61781c60405180602001604052808a60000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525083619a69565b600001516040518060400160405280601a81526020017f6e657720696e6465782065786365656473203232342062697473000000000000815250619a99565b8760000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055508487600001601c6101000a81548163ffffffff021916908363ffffffff160217905550505050617906565b6000811115617905578184600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505b5b505050505050565b6000601160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690506000601360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081601360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600081148015617ade57506ec097ce7bc90715b34b9f10000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682115b15617b14576ec097ce7bc90715b34b9f10000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690505b617b1c619fc0565b6040518060200160405280617b318585618c4f565b81525090506000617bf98873ffffffffffffffffffffffffffffffffffffffff166395dd9193896040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015617bb857600080fd5b505afa158015617bcc573d6000803e3d6000fd5b505050506040513d6020811015617be257600080fd5b810190808051906020019092919050505087619a00565b90506000617c078284619b6c565b90506000617c54601460008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483618ce3565b905080601460008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a68489604051808381526020018281526020019250505060405180910390a350505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480617dbd5750600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b905090565b600080617dcd6151dd565b905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015617e4e57600080fd5b505afa158015617e62573d6000803e3d6000fd5b505050506040513d6020811015617e7857600080fd5b81019080805190602001909291905050509050600084118015617e9b5750808411155b15617f6e578173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86866040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015617f2757600080fd5b505af1158015617f3b573d6000803e3d6000fd5b505050506040513d6020811015617f5157600080fd5b810190808051906020019092919050505050600092505050617f74565b83925050505b92915050565b6000806000617f87619fd3565b60006060600860008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561804a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311618000575b5050505050905060008090505b815181101561841357600082828151811061806e57fe5b602002602001015190508073ffffffffffffffffffffffffffffffffffffffff1663c37f68e28d6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060806040518083038186803b1580156180f557600080fd5b505afa158015618109573d6000803e3d6000fd5b505050506040513d608081101561811f57600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505088604001896060018a608001838152508381525083815250839750505050506000841461819057600f600080819150809050975097509750505050505061845f565b6040518060200160405280600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548152508560c00181905250604051806020016040528086608001518152508560e00181905250600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc57d4df826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156182a357600080fd5b505afa1580156182b7573d6000803e3d6000fd5b505050506040513d60208110156182cd57600080fd5b81019080805190602001909291905050508560a001818152505060008560a00151141561830f57600d600080819150809050975097509750505050505061845f565b60405180602001604052808660a0015181525085610100018190525061834b6183408660c001518760e001516198f5565b8661010001516198f5565b85610120018190525061836c85610120015186604001518760000151619b9c565b85600001818152505061838d85610100015186606001518760200151619b9c565b8560200181815250508a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415618405576183de8561012001518b8760200151619b9c565b8560200181815250506183fb8561010001518a8760200151619b9c565b8560200181815250505b508080600101915050618057565b508260200151836000015111156184445760008360200151846000015103600080905095509550955050505061845f565b60008084600001518560200151038191509550955095505050505b9450945094915050565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006185386184fd613900565b6040518060400160405280601c81526020017f626c6f636b206e756d62657220657863656564732033322062697473000000008152506196ab565b905060006185668263ffffffff1685600001601c9054906101000a900463ffffffff1663ffffffff16618c4f565b90506000811180156185785750600083115b156187635760008573ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156185c557600080fd5b505afa1580156185d9573d6000803e3d6000fd5b505050506040513d60208110156185ef57600080fd5b81019080805190602001909291905050509050600061860e8386618c99565b9050618618619fc0565b600083116186355760405180602001604052806000815250618640565b61863f8284619a29565b5b90506186e66186a760405180602001604052808a60000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525083619a69565b600001516040518060400160405280601a81526020017f6e657720696e6465782065786365656473203232342062697473000000000000815250619a99565b8760000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055508487600001601c6101000a81548163ffffffff021916908363ffffffff160217905550505050618791565b6000811115618790578184600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505b5b5050505050565b6000601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690506000601260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081601260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008114801561896857506ec097ce7bc90715b34b9f10000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682115b1561899e576ec097ce7bc90715b34b9f10000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690505b6189a6619fc0565b60405180602001604052806189bb8585618c4f565b815250905060008673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015618a3f57600080fd5b505afa158015618a53573d6000803e3d6000fd5b505050506040513d6020811015618a6957600080fd5b810190808051906020019092919050505090506000618a888284619b6c565b90506000618ad5601460008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483618ce3565b905080601460008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a8489604051808381526020018281526020019250505060405180910390a3505050505050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836011811115618bc257fe5b836013811115618bce57fe5b600060405180848152602001838152602001828152602001935050505060405180910390a1826011811115618bff57fe5b905092915050565b6000806000618c1a846000806000617f7a565b9250925092509193909250565b6000618c31619f81565b618c3b8484619bce565b9050618c4681619bfa565b91505092915050565b6000618c9183836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f770000000000000000000000815250619c19565b905092915050565b6000618cdb83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250619cd3565b905092915050565b6000618d2583836040518060400160405280601181526020017f6164646974696f6e206f766572666c6f77000000000000000000000000000000815250619db8565b905092915050565b600080600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff16618d91576009915050618f90565b600115158160020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415618df6576000915050618f90565b60018160020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208490806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550507f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a58484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a160009150505b92915050565b60008090505b600d8054905081101561908f578173ffffffffffffffffffffffffffffffffffffffff16600d8281548110618fcd57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415619082576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6d61726b657420616c726561647920616464656400000000000000000000000081525060200191505060405180910390fd5b8080600101915050618f9c565b50600d8190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000619141619106613900565b6040518060400160405280601c81526020017f626c6f636b206e756d62657220657863656564732033322062697473000000008152506196ab565b90506000601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000601160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008260000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16141561927f576ec097ce7bc90715b34b9f10000000008260000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055505b60008160000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161415619335576ec097ce7bc90715b34b9f10000000008160000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055505b8281600001601c6101000a81548163ffffffff021916908363ffffffff160217905582600001601c6101000a81548163ffffffff021916908363ffffffff16021790555050505050565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff16619446576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f636f6d70206d61726b6574206973206e6f74206c69737465640000000000000081525060200191505060405180910390fd5b82601a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146195285761949584618469565b82601a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff167fdeafccd0c0b768b2529f7dcbbe58e155d6023059150b7490ed4535cc3744b92d846040518082815260200191505060405180910390a25b81601960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146196a557619576619f81565b60405180602001604052808673ffffffffffffffffffffffffffffffffffffffff1663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156195c757600080fd5b505afa1580156195db573d6000803e3d6000fd5b505050506040513d60208110156195f157600080fd5b8101908080519060200190929190505050815250905061961185826175d5565b82601960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff167f20af8e791cc98f74b2d7a391c80980ca8e5aebf3d4060bf581997b6acae2e537846040518082815260200191505060405180910390a2505b50505050565b60006401000000008310829061975c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619721578082015181840152602081019050619706565b50505050905090810190601f16801561974e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082905092915050565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff166197d057600960118111156197c957fe5b90506198ee565b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16619875576000601181111561986e57fe5b90506198ee565b6000806198858587866000617f7a565b92505091506000601181111561989757fe5b8260118111156198a357fe5b146198bd578160118111156198b457fe5b925050506198ee565b60008111156198dc57600460118111156198d357fe5b925050506198ee565b600060118111156198e957fe5b925050505b9392505050565b6198fd619f81565b6040518060200160405280670de0b6b3a764000061992386600001518660000151618c99565b8161992a57fe5b04815250905092915050565b61993e619f81565b604051806020016040528061996c6199628660000151670de0b6b3a7640000618c99565b8560000151619e77565b815250905092915050565b60008160000151836000015110905092915050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460118111156199bb57fe5b8460138111156199c757fe5b8460405180848152602001838152602001828152602001935050505060405180910390a18360118111156199f757fe5b90509392505050565b6000619a21619a1784670de0b6b3a7640000618c99565b8360000151619e77565b905092915050565b619a31619fc0565b6040518060200160405280619a5e619a58866ec097ce7bc90715b34b9f1000000000618c99565b85619e77565b815250905092915050565b619a71619fc0565b6040518060200160405280619a8e85600001518560000151618ce3565b815250905092915050565b60007c010000000000000000000000000000000000000000000000000000000083108290619b62576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619b27578082015181840152602081019050619b0c565b50505050905090810190601f168015619b545780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082905092915050565b60006ec097ce7bc90715b34b9f1000000000619b8c848460000151618c99565b81619b9357fe5b04905092915050565b6000619ba6619f81565b619bb08585619bce565b9050619bc4619bbe82619bfa565b84618ce3565b9150509392505050565b619bd6619f81565b6040518060200160405280619bef856000015185618c99565b815250905092915050565b6000670de0b6b3a7640000826000015181619c1157fe5b049050919050565b6000838311158290619cc6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619c8b578082015181840152602081019050619c70565b50505050905090810190601f168015619cb85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600080841480619ce35750600083145b15619cf15760009050619db1565b6000838502905083858281619d0257fe5b04148390619dab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619d70578082015181840152602081019050619d55565b50505050905090810190601f168015619d9d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50809150505b9392505050565b6000808385019050848110158390619e6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619e30578082015181840152602081019050619e15565b50505050905090810190601f168015619e5d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50809150509392505050565b6000619eb983836040518060400160405280600e81526020017f646976696465206279207a65726f000000000000000000000000000000000000815250619ec1565b905092915050565b60008083118290619f6d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619f32578082015181840152602081019050619f17565b50505050905090810190601f168015619f5f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50828481619f7757fe5b0490509392505050565b6040518060200160405280600081525090565b815481835581811115619fbb57818360005260206000209182019101619fba919061a03e565b5b505050565b6040518060200160405280600081525090565b60405180610140016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200161a01161a063565b815260200161a01e61a063565b815260200161a02b61a063565b815260200161a03861a063565b81525090565b61a06091905b8082111561a05c57600081600090555060010161a044565b5090565b90565b604051806020016040528060008152509056fe63616e6e6f742070617573652061206d61726b65742074686174206973206e6f74206c697374656443616e206e6f74207265706179206d6f7265207468616e2074686520746f74616c20626f72726f776f6e6c7920706175736520677561726469616e20616e642061646d696e2063616e2070617573656f6e6c792061646d696e2063616e2073657420626f72726f772063617020677561726469616e6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616e2063616e2073657420626f72726f772063617073657869744d61726b65743a206765744163636f756e74536e617073686f74206661696c6564436f6d7074726f6c6c65723a3a5f736574436f6d7053706565647320696e76616c696420696e7075746f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676520627261696e73a265627a7a72315820eb9e633c98cd4140276d27d4b411fee5ac94eb20f02bed3979ea22ae6470728c64736f6c63430005110032 \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/Comptroller.sol b/benchmark/ethereum/compound/contract/Comptroller.sol new file mode 100644 index 0000000..b61a61a --- /dev/null +++ b/benchmark/ethereum/compound/contract/Comptroller.sol @@ -0,0 +1,1451 @@ +pragma solidity ^0.5.16; + +import "./CToken.sol"; +import "./ErrorReporter.sol"; +import "./PriceOracle.sol"; +import "./ComptrollerInterface.sol"; +import "./ComptrollerStorage.sol"; +import "./Unitroller.sol"; +import "./Governance/Comp.sol"; + +/** + * @title Compound's Comptroller Contract + * @author Compound + */ +contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError { + /// @notice Emitted when an admin supports a market + event MarketListed(CToken cToken); + + /// @notice Emitted when an account enters a market + event MarketEntered(CToken cToken, address account); + + /// @notice Emitted when an account exits a market + event MarketExited(CToken cToken, address account); + + /// @notice Emitted when close factor is changed by admin + event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa); + + /// @notice Emitted when a collateral factor is changed by admin + event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + + /// @notice Emitted when liquidation incentive is changed by admin + event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa); + + /// @notice Emitted when price oracle is changed + event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle); + + /// @notice Emitted when pause guardian is changed + event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian); + + /// @notice Emitted when an action is paused globally + event ActionPaused(string action, bool pauseState); + + /// @notice Emitted when an action is paused on a market + event ActionPaused(CToken cToken, string action, bool pauseState); + + /// @notice Emitted when a new borrow-side COMP speed is calculated for a market + event CompBorrowSpeedUpdated(CToken indexed cToken, uint newSpeed); + + /// @notice Emitted when a new supply-side COMP speed is calculated for a market + event CompSupplySpeedUpdated(CToken indexed cToken, uint newSpeed); + + /// @notice Emitted when a new COMP speed is set for a contributor + event ContributorCompSpeedUpdated(address indexed contributor, uint newSpeed); + + /// @notice Emitted when COMP is distributed to a supplier + event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex); + + /// @notice Emitted when COMP is distributed to a borrower + event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex); + + /// @notice Emitted when borrow cap for a cToken is changed + event NewBorrowCap(CToken indexed cToken, uint newBorrowCap); + + /// @notice Emitted when borrow cap guardian is changed + event NewBorrowCapGuardian(address oldBorrowCapGuardian, address newBorrowCapGuardian); + + /// @notice Emitted when COMP is granted by admin + event CompGranted(address recipient, uint amount); + + /// @notice The initial COMP index for a market + uint224 public constant compInitialIndex = 1e36; + + // closeFactorMantissa must be strictly greater than this value + uint internal constant closeFactorMinMantissa = 0.05e18; // 0.05 + + // closeFactorMantissa must not exceed this value + uint internal constant closeFactorMaxMantissa = 0.9e18; // 0.9 + + // No collateralFactorMantissa may exceed this value + uint internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9 + + constructor() public { + admin = msg.sender; + } + + /*** Assets You Are In ***/ + + /** + * @notice Returns the assets an account has entered + * @param account The address of the account to pull assets for + * @return A dynamic list with the assets the account has entered + */ + function getAssetsIn(address account) external view returns (CToken[] memory) { + CToken[] memory assetsIn = accountAssets[account]; + + return assetsIn; + } + + /** + * @notice Returns whether the given account is entered in the given asset + * @param account The address of the account to check + * @param cToken The cToken to check + * @return True if the account is in the asset, otherwise false. + */ + function checkMembership(address account, CToken cToken) external view returns (bool) { + return markets[address(cToken)].accountMembership[account]; + } + + /** + * @notice Add assets to be included in account liquidity calculation + * @param cTokens The list of addresses of the cToken markets to be enabled + * @return Success indicator for whether each corresponding market was entered + */ + function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { + uint len = cTokens.length; + + uint[] memory results = new uint[](len); + for (uint i = 0; i < len; i++) { + CToken cToken = CToken(cTokens[i]); + + results[i] = uint(addToMarketInternal(cToken, msg.sender)); + } + + return results; + } + + function enterOneMarkets(address cTokenAddr) public returns (uint) { + CToken cToken = CToken(cTokenAddr); + return uint(addToMarketInternal(cToken, msg.sender)); + } + + /** + * @notice Add the market to the borrower's "assets in" for liquidity calculations + * @param cToken The market to enter + * @param borrower The address of the account to modify + * @return Success indicator for whether the market was entered + */ + function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { + Market storage marketToJoin = markets[address(cToken)]; + + if (!marketToJoin.isListed) { + // market is not listed, cannot join + return Error.MARKET_NOT_LISTED; + } + + if (marketToJoin.accountMembership[borrower] == true) { + // already joined + return Error.NO_ERROR; + } + + // survived the gauntlet, add to list + // NOTE: we store these somewhat redundantly as a significant optimization + // this avoids having to iterate through the list for the most common use cases + // that is, only when we need to perform liquidity checks + // and not whenever we want to check if an account is in a particular market + marketToJoin.accountMembership[borrower] = true; + accountAssets[borrower].push(cToken); + + emit MarketEntered(cToken, borrower); + + return Error.NO_ERROR; + } + + /** + * @notice Removes asset from sender's account liquidity calculation + * @dev Sender must not have an outstanding borrow balance in the asset, + * or be providing necessary collateral for an outstanding borrow. + * @param cTokenAddress The address of the asset to be removed + * @return Whether or not the account successfully exited the market + */ + function exitMarket(address cTokenAddress) external returns (uint) { + CToken cToken = CToken(cTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the cToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code + + /* Fail if the sender has a borrow balance */ + if (amountOwed != 0) { + return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED); + } + + /* Fail if the sender is not permitted to redeem all of their tokens */ + uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + if (allowed != 0) { + return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); + } + + Market storage marketToExit = markets[address(cToken)]; + + /* Return true if the sender is not already ‘in’ the market */ + if (!marketToExit.accountMembership[msg.sender]) { + return uint(Error.NO_ERROR); + } + + /* Set cToken account membership to false */ + delete marketToExit.accountMembership[msg.sender]; + + /* Delete cToken from the account’s list of assets */ + // load into memory for faster iteration + CToken[] memory userAssetList = accountAssets[msg.sender]; + uint len = userAssetList.length; + uint assetIndex = len; + for (uint i = 0; i < len; i++) { + if (userAssetList[i] == cToken) { + assetIndex = i; + break; + } + } + + // We *must* have found the asset in the list or our redundant data structure is broken + assert(assetIndex < len); + + // copy last item in list to location of item to be removed, reduce length by 1 + CToken[] storage storedList = accountAssets[msg.sender]; + storedList[assetIndex] = storedList[storedList.length - 1]; + storedList.length--; + + emit MarketExited(cToken, msg.sender); + + return uint(Error.NO_ERROR); + } + + /*** Policy Hooks ***/ + + /** + * @notice Checks if the account should be allowed to mint tokens in the given market + * @param cToken The market to verify the mint against + * @param minter The account which would get the minted tokens + * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens + * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!mintGuardianPaused[cToken], "mint is paused"); + + // Shh - currently unused + minter; + mintAmount; + + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + // Keep the flywheel moving + updateCompSupplyIndex(cToken); + distributeSupplierComp(cToken, minter); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates mint and reverts on rejection. May emit logs. + * @param cToken Asset being minted + * @param minter The address minting the tokens + * @param actualMintAmount The amount of the underlying asset being minted + * @param mintTokens The number of tokens being minted + */ + function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) external { + // Shh - currently unused + cToken; + minter; + actualMintAmount; + mintTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the account should be allowed to redeem tokens in the given market + * @param cToken The market to verify the redeem against + * @param redeemer The account which would redeem the tokens + * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { + uint allowed = redeemAllowedInternal(cToken, redeemer, redeemTokens); + if (allowed != uint(Error.NO_ERROR)) { + return allowed; + } + + // Keep the flywheel moving + updateCompSupplyIndex(cToken); + distributeSupplierComp(cToken, redeemer); + + return uint(Error.NO_ERROR); + } + + function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ + if (!markets[cToken].accountMembership[redeemer]) { + return uint(Error.NO_ERROR); + } + + /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + if (err != Error.NO_ERROR) { + return uint(err); + } + if (shortfall > 0) { + return uint(Error.INSUFFICIENT_LIQUIDITY); + } + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates redeem and reverts on rejection. May emit logs. + * @param cToken Asset being redeemed + * @param redeemer The address redeeming the tokens + * @param redeemAmount The amount of the underlying asset being redeemed + * @param redeemTokens The number of tokens being redeemed + */ + function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + // Shh - currently unused + cToken; + redeemer; + + // Require tokens is zero or amount is also zero + if (redeemTokens == 0 && redeemAmount > 0) { + revert("redeemTokens zero"); + } + } + + /** + * @notice Checks if the account should be allowed to borrow the underlying asset of the given market + * @param cToken The market to verify the borrow against + * @param borrower The account which would borrow the asset + * @param borrowAmount The amount of underlying the account would borrow + * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!borrowGuardianPaused[cToken], "borrow is paused"); + + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + if (!markets[cToken].accountMembership[borrower]) { + // only cTokens may call borrowAllowed if borrower not in market + require(msg.sender == cToken, "sender must be cToken"); + + // attempt to add borrower to the market + Error err = addToMarketInternal(CToken(msg.sender), borrower); + if (err != Error.NO_ERROR) { + return uint(err); + } + + // it should be impossible to break the important invariant + assert(markets[cToken].accountMembership[borrower]); + } + + if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + return uint(Error.PRICE_ERROR); + } + + + uint borrowCap = borrowCaps[cToken]; + // Borrow cap of 0 corresponds to unlimited borrowing + if (borrowCap != 0) { + uint totalBorrows = CToken(cToken).totalBorrows(); + uint nextTotalBorrows = add_(totalBorrows, borrowAmount); + require(nextTotalBorrows < borrowCap, "market borrow cap reached"); + } + + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + if (err != Error.NO_ERROR) { + return uint(err); + } + if (shortfall > 0) { + return uint(Error.INSUFFICIENT_LIQUIDITY); + } + + // Keep the flywheel moving + Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); + updateCompBorrowIndex(cToken, borrowIndex); + distributeBorrowerComp(cToken, borrower, borrowIndex); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates borrow and reverts on rejection. May emit logs. + * @param cToken Asset whose underlying is being borrowed + * @param borrower The address borrowing the underlying + * @param borrowAmount The amount of the underlying asset requested to borrow + */ + function borrowVerify(address cToken, address borrower, uint borrowAmount) external { + // Shh - currently unused + cToken; + borrower; + borrowAmount; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the account should be allowed to repay a borrow in the given market + * @param cToken The market to verify the repay against + * @param payer The account which would repay the asset + * @param borrower The account which would borrowed the asset + * @param repayAmount The amount of the underlying asset the account would repay + * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function repayBorrowAllowed( + address cToken, + address payer, + address borrower, + uint repayAmount) external returns (uint) { + // Shh - currently unused + payer; + borrower; + repayAmount; + + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + // Keep the flywheel moving + Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); + updateCompBorrowIndex(cToken, borrowIndex); + distributeBorrowerComp(cToken, borrower, borrowIndex); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates repayBorrow and reverts on rejection. May emit logs. + * @param cToken Asset being repaid + * @param payer The address repaying the borrow + * @param borrower The address of the borrower + * @param actualRepayAmount The amount of underlying being repaid + */ + function repayBorrowVerify( + address cToken, + address payer, + address borrower, + uint actualRepayAmount, + uint borrowerIndex) external { + // Shh - currently unused + cToken; + payer; + borrower; + actualRepayAmount; + borrowerIndex; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the liquidation should be allowed to occur + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param repayAmount The amount of underlying being repaid + */ + function liquidateBorrowAllowed( + address cTokenBorrowed, + address cTokenCollateral, + address liquidator, + address borrower, + uint repayAmount) external returns (uint) { + // Shh - currently unused + liquidator; + + if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + + /* allow accounts to be liquidated if the market is deprecated */ + if (isDeprecated(CToken(cTokenBorrowed))) { + require(borrowBalance >= repayAmount, "Can not repay more than the total borrow"); + } else { + /* The borrower must have shortfall in order to be liquidatable */ + (Error err, , uint shortfall) = getAccountLiquidityInternal(borrower); + if (err != Error.NO_ERROR) { + return uint(err); + } + + if (shortfall == 0) { + return uint(Error.INSUFFICIENT_SHORTFALL); + } + + /* The liquidator may not repay more than what is allowed by the closeFactor */ + uint maxClose = mul_ScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); + if (repayAmount > maxClose) { + return uint(Error.TOO_MUCH_REPAY); + } + } + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param actualRepayAmount The amount of underlying being repaid + */ + function liquidateBorrowVerify( + address cTokenBorrowed, + address cTokenCollateral, + address liquidator, + address borrower, + uint actualRepayAmount, + uint seizeTokens) external { + // Shh - currently unused + cTokenBorrowed; + cTokenCollateral; + liquidator; + borrower; + actualRepayAmount; + seizeTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the seizing of assets should be allowed to occur + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param seizeTokens The number of collateral tokens to seize + */ + function seizeAllowed( + address cTokenCollateral, + address cTokenBorrowed, + address liquidator, + address borrower, + uint seizeTokens) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!seizeGuardianPaused, "seize is paused"); + + // Shh - currently unused + seizeTokens; + + if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + return uint(Error.COMPTROLLER_MISMATCH); + } + + // Keep the flywheel moving + updateCompSupplyIndex(cTokenCollateral); + distributeSupplierComp(cTokenCollateral, borrower); + distributeSupplierComp(cTokenCollateral, liquidator); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates seize and reverts on rejection. May emit logs. + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param seizeTokens The number of collateral tokens to seize + */ + function seizeVerify( + address cTokenCollateral, + address cTokenBorrowed, + address liquidator, + address borrower, + uint seizeTokens) external { + // Shh - currently unused + cTokenCollateral; + cTokenBorrowed; + liquidator; + borrower; + seizeTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the account should be allowed to transfer tokens in the given market + * @param cToken The market to verify the transfer against + * @param src The account which sources the tokens + * @param dst The account which receives the tokens + * @param transferTokens The number of cTokens to transfer + * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!transferGuardianPaused, "transfer is paused"); + + // Currently the only consideration is whether or not + // the src is allowed to redeem this many tokens + uint allowed = redeemAllowedInternal(cToken, src, transferTokens); + if (allowed != uint(Error.NO_ERROR)) { + return allowed; + } + + // Keep the flywheel moving + updateCompSupplyIndex(cToken); + distributeSupplierComp(cToken, src); + distributeSupplierComp(cToken, dst); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates transfer and reverts on rejection. May emit logs. + * @param cToken Asset being transferred + * @param src The account which sources the tokens + * @param dst The account which receives the tokens + * @param transferTokens The number of cTokens to transfer + */ + function transferVerify(address cToken, address src, address dst, uint transferTokens) external { + // Shh - currently unused + cToken; + src; + dst; + transferTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /*** Liquidity/Liquidation Calculations ***/ + + /** + * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. + * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * whereas `borrowBalance` is the amount of underlying that the account has borrowed. + */ + struct AccountLiquidityLocalVars { + uint sumCollateral; + uint sumBorrowPlusEffects; + uint cTokenBalance; + uint borrowBalance; + uint exchangeRateMantissa; + uint oraclePriceMantissa; + Exp collateralFactor; + Exp exchangeRate; + Exp oraclePrice; + Exp tokensToDenom; + } + + /** + * @notice Determine the current account liquidity wrt collateral requirements + * @return (possible error code (semi-opaque), + account liquidity in excess of collateral requirements, + * account shortfall below collateral requirements) + */ + function getAccountLiquidity(address account) public view returns (uint, uint, uint) { + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + + return (uint(err), liquidity, shortfall); + } + + /** + * @notice Determine the current account liquidity wrt collateral requirements + * @return (possible error code, + account liquidity in excess of collateral requirements, + * account shortfall below collateral requirements) + */ + function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { + return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + } + + /** + * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed + * @param cTokenModify The market to hypothetically redeem/borrow in + * @param account The account to determine liquidity for + * @param redeemTokens The number of tokens to hypothetically redeem + * @param borrowAmount The amount of underlying to hypothetically borrow + * @return (possible error code (semi-opaque), + hypothetical account liquidity in excess of collateral requirements, + * hypothetical account shortfall below collateral requirements) + */ + function getHypotheticalAccountLiquidity( + address account, + address cTokenModify, + uint redeemTokens, + uint borrowAmount) public view returns (uint, uint, uint) { + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + return (uint(err), liquidity, shortfall); + } + + /** + * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed + * @param cTokenModify The market to hypothetically redeem/borrow in + * @param account The account to determine liquidity for + * @param redeemTokens The number of tokens to hypothetically redeem + * @param borrowAmount The amount of underlying to hypothetically borrow + * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * without calculating accumulated interest. + * @return (possible error code, + hypothetical account liquidity in excess of collateral requirements, + * hypothetical account shortfall below collateral requirements) + */ + function getHypotheticalAccountLiquidityInternal( + address account, + CToken cTokenModify, + uint redeemTokens, + uint borrowAmount) internal view returns (Error, uint, uint) { + + AccountLiquidityLocalVars memory vars; // Holds all our calculation results + uint oErr; + + // For each asset the account is in + CToken[] memory assets = accountAssets[account]; + for (uint i = 0; i < assets.length; i++) { + CToken asset = assets[i]; + + // Read the balances and exchange rate from the cToken + (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades + return (Error.SNAPSHOT_ERROR, 0, 0); + } + vars.collateralFactor = Exp({mantissa: markets[address(asset)].collateralFactorMantissa}); + vars.exchangeRate = Exp({mantissa: vars.exchangeRateMantissa}); + + // Get the normalized price of the asset + vars.oraclePriceMantissa = oracle.getUnderlyingPrice(asset); + if (vars.oraclePriceMantissa == 0) { + return (Error.PRICE_ERROR, 0, 0); + } + vars.oraclePrice = Exp({mantissa: vars.oraclePriceMantissa}); + + // Pre-compute a conversion factor from tokens -> ether (normalized price value) + vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice); + + // sumCollateral += tokensToDenom * cTokenBalance + vars.sumCollateral = mul_ScalarTruncateAddUInt(vars.tokensToDenom, vars.cTokenBalance, vars.sumCollateral); + + // sumBorrowPlusEffects += oraclePrice * borrowBalance + vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.oraclePrice, vars.borrowBalance, vars.sumBorrowPlusEffects); + + // Calculate effects of interacting with cTokenModify + if (asset == cTokenModify) { + // redeem effect + // sumBorrowPlusEffects += tokensToDenom * redeemTokens + vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.tokensToDenom, redeemTokens, vars.sumBorrowPlusEffects); + + // borrow effect + // sumBorrowPlusEffects += oraclePrice * borrowAmount + vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.oraclePrice, borrowAmount, vars.sumBorrowPlusEffects); + } + } + + // These are safe, as the underflow condition is checked first + if (vars.sumCollateral > vars.sumBorrowPlusEffects) { + return (Error.NO_ERROR, vars.sumCollateral - vars.sumBorrowPlusEffects, 0); + } else { + return (Error.NO_ERROR, 0, vars.sumBorrowPlusEffects - vars.sumCollateral); + } + } + + /** + * @notice Calculate number of tokens of collateral asset to seize given an underlying amount + * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) + * @param cTokenBorrowed The address of the borrowed cToken + * @param cTokenCollateral The address of the collateral cToken + * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens + * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + */ + function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { + /* Read oracle prices for borrowed and collateral markets */ + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { + return (uint(Error.PRICE_ERROR), 0); + } + + /* + * Get the exchange rate and calculate the number of collateral tokens to seize: + * seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral + * seizeTokens = seizeAmount / exchangeRate + * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) + */ + uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint seizeTokens; + Exp memory numerator; + Exp memory denominator; + Exp memory ratio; + + numerator = mul_(Exp({mantissa: liquidationIncentiveMantissa}), Exp({mantissa: priceBorrowedMantissa})); + denominator = mul_(Exp({mantissa: priceCollateralMantissa}), Exp({mantissa: exchangeRateMantissa})); + ratio = div_(numerator, denominator); + + seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount); + + return (uint(Error.NO_ERROR), seizeTokens); + } + + /*** Admin Functions ***/ + + /** + * @notice Sets a new price oracle for the comptroller + * @dev Admin function to set a new price oracle + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function _setPriceOracle(PriceOracle newOracle) public returns (uint) { + // Check caller is admin + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_PRICE_ORACLE_OWNER_CHECK); + } + + // Track the old oracle for the comptroller + PriceOracle oldOracle = oracle; + + // Set comptroller's oracle to newOracle + oracle = newOracle; + + // Emit NewPriceOracle(oldOracle, newOracle) + emit NewPriceOracle(oldOracle, newOracle); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Sets the closeFactor used when liquidating borrows + * @dev Admin function to set closeFactor + * @param newCloseFactorMantissa New close factor, scaled by 1e18 + * @return uint 0=success, otherwise a failure + */ + function _setCloseFactor(uint newCloseFactorMantissa) external returns (uint) { + // Check caller is admin + require(msg.sender == admin, "only admin can set close factor"); + + uint oldCloseFactorMantissa = closeFactorMantissa; + closeFactorMantissa = newCloseFactorMantissa; + emit NewCloseFactor(oldCloseFactorMantissa, closeFactorMantissa); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Sets the collateralFactor for a market + * @dev Admin function to set per-market collateralFactor + * @param cToken The market to set the factor on + * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 + * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) + */ + function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { + // Check caller is admin + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); + } + + // Verify market is listed + Market storage market = markets[address(cToken)]; + if (!market.isListed) { + return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); + } + + Exp memory newCollateralFactorExp = Exp({mantissa: newCollateralFactorMantissa}); + + // Check collateral factor <= 0.9 + Exp memory highLimit = Exp({mantissa: collateralFactorMaxMantissa}); + if (lessThanExp(highLimit, newCollateralFactorExp)) { + return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION); + } + + // If collateral factor != 0, fail if price == 0 + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); + } + + // Set market's collateral factor to new collateral factor, remember old value + uint oldCollateralFactorMantissa = market.collateralFactorMantissa; + market.collateralFactorMantissa = newCollateralFactorMantissa; + + // Emit event with asset, old collateral factor, and new collateral factor + emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Sets liquidationIncentive + * @dev Admin function to set liquidationIncentive + * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18 + * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) + */ + function _setLiquidationIncentive(uint newLiquidationIncentiveMantissa) external returns (uint) { + // Check caller is admin + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_LIQUIDATION_INCENTIVE_OWNER_CHECK); + } + + // Save current value for use in log + uint oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa; + + // Set liquidation incentive to new incentive + liquidationIncentiveMantissa = newLiquidationIncentiveMantissa; + + // Emit event with old incentive, new incentive + emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Add the market to the markets mapping and set it as listed + * @dev Admin function to set isListed and add support for the market + * @param cToken The address of the market (token) to list + * @return uint 0=success, otherwise a failure. (See enum Error for details) + */ + function _supportMarket(CToken cToken) external returns (uint) { + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); + } + + if (markets[address(cToken)].isListed) { + return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); + } + + cToken.isCToken(); // Sanity check to make sure its really a CToken + + // Note that isComped is not in active use anymore + markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); + + _addMarketInternal(address(cToken)); + _initializeMarket(address(cToken)); + + emit MarketListed(cToken); + + return uint(Error.NO_ERROR); + } + + function _addMarketInternal(address cToken) internal { + for (uint i = 0; i < allMarkets.length; i ++) { + require(allMarkets[i] != CToken(cToken), "market already added"); + } + allMarkets.push(CToken(cToken)); + } + + function _initializeMarket(address cToken) internal { + uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); + + CompMarketState storage supplyState = compSupplyState[cToken]; + CompMarketState storage borrowState = compBorrowState[cToken]; + + /* + * Update market state indices + */ + if (supplyState.index == 0) { + // Initialize supply state index with default value + supplyState.index = compInitialIndex; + } + + if (borrowState.index == 0) { + // Initialize borrow state index with default value + borrowState.index = compInitialIndex; + } + + /* + * Update market state block numbers + */ + supplyState.block = borrowState.block = blockNumber; + } + + + /** + * @notice Set the given borrow caps for the given cToken markets. Borrowing that brings total borrows to or above borrow cap will revert. + * @dev Admin or borrowCapGuardian function to set the borrow caps. A borrow cap of 0 corresponds to unlimited borrowing. + * @param cTokens The addresses of the markets (tokens) to change the borrow caps for + * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing. + */ + function _setMarketBorrowCaps(CToken[] calldata cTokens, uint[] calldata newBorrowCaps) external { + require(msg.sender == admin || msg.sender == borrowCapGuardian, "only admin or borrow cap guardian can set borrow caps"); + + uint numMarkets = cTokens.length; + uint numBorrowCaps = newBorrowCaps.length; + + require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input"); + + for(uint i = 0; i < numMarkets; i++) { + borrowCaps[address(cTokens[i])] = newBorrowCaps[i]; + emit NewBorrowCap(cTokens[i], newBorrowCaps[i]); + } + } + + /** + * @notice Admin function to change the Borrow Cap Guardian + * @param newBorrowCapGuardian The address of the new Borrow Cap Guardian + */ + function _setBorrowCapGuardian(address newBorrowCapGuardian) external { + require(msg.sender == admin, "only admin can set borrow cap guardian"); + + // Save current value for inclusion in log + address oldBorrowCapGuardian = borrowCapGuardian; + + // Store borrowCapGuardian with value newBorrowCapGuardian + borrowCapGuardian = newBorrowCapGuardian; + + // Emit NewBorrowCapGuardian(OldBorrowCapGuardian, NewBorrowCapGuardian) + emit NewBorrowCapGuardian(oldBorrowCapGuardian, newBorrowCapGuardian); + } + + /** + * @notice Admin function to change the Pause Guardian + * @param newPauseGuardian The address of the new Pause Guardian + * @return uint 0=success, otherwise a failure. (See enum Error for details) + */ + function _setPauseGuardian(address newPauseGuardian) public returns (uint) { + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_PAUSE_GUARDIAN_OWNER_CHECK); + } + + // Save current value for inclusion in log + address oldPauseGuardian = pauseGuardian; + + // Store pauseGuardian with value newPauseGuardian + pauseGuardian = newPauseGuardian; + + // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian) + emit NewPauseGuardian(oldPauseGuardian, pauseGuardian); + + return uint(Error.NO_ERROR); + } + + function _setMintPaused(CToken cToken, bool state) public returns (bool) { + require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + mintGuardianPaused[address(cToken)] = state; + emit ActionPaused(cToken, "Mint", state); + return state; + } + + function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { + require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + borrowGuardianPaused[address(cToken)] = state; + emit ActionPaused(cToken, "Borrow", state); + return state; + } + + function _setTransferPaused(bool state) public returns (bool) { + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + transferGuardianPaused = state; + emit ActionPaused("Transfer", state); + return state; + } + + function _setSeizePaused(bool state) public returns (bool) { + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + seizeGuardianPaused = state; + emit ActionPaused("Seize", state); + return state; + } + + function _become(Unitroller unitroller) public { + require(msg.sender == unitroller.admin(), "only unitroller admin can change brains"); + require(unitroller._acceptImplementation() == 0, "change not authorized"); + + // TODO: Remove this post upgrade + Comptroller(address(unitroller))._upgradeSplitCompRewards(); + } + + function _upgradeSplitCompRewards() public { + require(msg.sender == comptrollerImplementation, "only brains can become itself"); + + uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); + + // compSpeeds -> compBorrowSpeeds & compSupplySpeeds t + for (uint i = 0; i < allMarkets.length; i ++) { + compBorrowSpeeds[address(allMarkets[i])] = compSupplySpeeds[address(allMarkets[i])] = compSpeeds[address(allMarkets[i])]; + delete compSpeeds[address(allMarkets[i])]; + + /* + * Ensure supply and borrow state indices are all set. If not set, update to default value + */ + CompMarketState storage supplyState = compSupplyState[address(allMarkets[i])]; + CompMarketState storage borrowState = compBorrowState[address(allMarkets[i])]; + + if (supplyState.index == 0) { + // Initialize supply state index with default value + supplyState.index = compInitialIndex; + supplyState.block = blockNumber; + } + + if (borrowState.index == 0) { + // Initialize borrow state index with default value + borrowState.index = compInitialIndex; + borrowState.block = blockNumber; + } + } + } + + /** + * @notice Checks caller is admin, or this contract is becoming the new implementation + */ + function adminOrInitializing() internal view returns (bool) { + return msg.sender == admin || msg.sender == comptrollerImplementation; + } + + /*** Comp Distribution ***/ + + /** + * @notice Set COMP speed for a single market + * @param cToken The market whose COMP speed to update + * @param supplySpeed New supply-side COMP speed for market + * @param borrowSpeed New borrow-side COMP speed for market + */ + function setCompSpeedInternal(CToken cToken, uint supplySpeed, uint borrowSpeed) internal { + Market storage market = markets[address(cToken)]; + require(market.isListed, "comp market is not listed"); + + if (compSupplySpeeds[address(cToken)] != supplySpeed) { + // Supply speed updated so let's update supply state to ensure that + // 1. COMP accrued properly for the old speed, and + // 2. COMP accrued at the new speed starts after this block. + updateCompSupplyIndex(address(cToken)); + + // Update speed and emit event + compSupplySpeeds[address(cToken)] = supplySpeed; + emit CompSupplySpeedUpdated(cToken, supplySpeed); + } + + if (compBorrowSpeeds[address(cToken)] != borrowSpeed) { + // Borrow speed updated so let's update borrow state to ensure that + // 1. COMP accrued properly for the old speed, and + // 2. COMP accrued at the new speed starts after this block. + Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); + updateCompBorrowIndex(address(cToken), borrowIndex); + + // Update speed and emit event + compBorrowSpeeds[address(cToken)] = borrowSpeed; + emit CompBorrowSpeedUpdated(cToken, borrowSpeed); + } + } + + /** + * @notice Accrue COMP to the market by updating the supply index + * @param cToken The market whose supply index to update + * @dev Index is a cumulative sum of the COMP per cToken accrued. + */ + function updateCompSupplyIndex(address cToken) internal { + CompMarketState storage supplyState = compSupplyState[cToken]; + uint supplySpeed = compSupplySpeeds[cToken]; + uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); + uint deltaBlocks = sub_(uint(blockNumber), uint(supplyState.block)); + if (deltaBlocks > 0 && supplySpeed > 0) { + uint supplyTokens = CToken(cToken).totalSupply(); + uint compAccrued = mul_(deltaBlocks, supplySpeed); + Double memory ratio = supplyTokens > 0 ? fraction(compAccrued, supplyTokens) : Double({mantissa: 0}); + supplyState.index = safe224(add_(Double({mantissa: supplyState.index}), ratio).mantissa, "new index exceeds 224 bits"); + supplyState.block = blockNumber; + } else if (deltaBlocks > 0) { + supplyState.block = blockNumber; + } + } + + /** + * @notice Accrue COMP to the market by updating the borrow index + * @param cToken The market whose borrow index to update + * @dev Index is a cumulative sum of the COMP per cToken accrued. + */ + function updateCompBorrowIndex(address cToken, Exp memory marketBorrowIndex) internal { + CompMarketState storage borrowState = compBorrowState[cToken]; + uint borrowSpeed = compBorrowSpeeds[cToken]; + uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); + uint deltaBlocks = sub_(uint(blockNumber), uint(borrowState.block)); + if (deltaBlocks > 0 && borrowSpeed > 0) { + uint borrowAmount = div_(CToken(cToken).totalBorrows(), marketBorrowIndex); + uint compAccrued = mul_(deltaBlocks, borrowSpeed); + Double memory ratio = borrowAmount > 0 ? fraction(compAccrued, borrowAmount) : Double({mantissa: 0}); + borrowState.index = safe224(add_(Double({mantissa: borrowState.index}), ratio).mantissa, "new index exceeds 224 bits"); + borrowState.block = blockNumber; + } else if (deltaBlocks > 0) { + borrowState.block = blockNumber; + } + } + + /** + * @notice Calculate COMP accrued by a supplier and possibly transfer it to them + * @param cToken The market in which the supplier is interacting + * @param supplier The address of the supplier to distribute COMP to + */ + function distributeSupplierComp(address cToken, address supplier) internal { + // TODO: Don't distribute supplier COMP if the user is not in the supplier market. + // This check should be as gas efficient as possible as distributeSupplierComp is called in many places. + // - We really don't want to call an external contract as that's quite expensive. + + CompMarketState storage supplyState = compSupplyState[cToken]; + uint supplyIndex = supplyState.index; + uint supplierIndex = compSupplierIndex[cToken][supplier]; + + // Update supplier's index to the current index since we are distributing accrued COMP + compSupplierIndex[cToken][supplier] = supplyIndex; + + if (supplierIndex == 0 && supplyIndex > compInitialIndex) { + // Covers the case where users supplied tokens before the market's supply state index was set. + // Rewards the user with COMP accrued from the start of when supplier rewards were first + // set for the market. + supplierIndex = compInitialIndex; + } + + // Calculate change in the cumulative sum of the COMP per cToken accrued + Double memory deltaIndex = Double({mantissa: sub_(supplyIndex, supplierIndex)}); + + uint supplierTokens = CToken(cToken).balanceOf(supplier); + + // Calculate COMP accrued: cTokenAmount * accruedPerCToken + uint supplierDelta = mul_(supplierTokens, deltaIndex); + + uint supplierAccrued = add_(compAccrued[supplier], supplierDelta); + compAccrued[supplier] = supplierAccrued; + + emit DistributedSupplierComp(CToken(cToken), supplier, supplierDelta, supplyIndex); + } + + /** + * @notice Calculate COMP accrued by a borrower and possibly transfer it to them + * @dev Borrowers will not begin to accrue until after the first interaction with the protocol. + * @param cToken The market in which the borrower is interacting + * @param borrower The address of the borrower to distribute COMP to + */ + function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex) internal { + // TODO: Don't distribute supplier COMP if the user is not in the borrower market. + // This check should be as gas efficient as possible as distributeBorrowerComp is called in many places. + // - We really don't want to call an external contract as that's quite expensive. + + CompMarketState storage borrowState = compBorrowState[cToken]; + uint borrowIndex = borrowState.index; + uint borrowerIndex = compBorrowerIndex[cToken][borrower]; + + // Update borrowers's index to the current index since we are distributing accrued COMP + compBorrowerIndex[cToken][borrower] = borrowIndex; + + if (borrowerIndex == 0 && borrowIndex > compInitialIndex) { + // Covers the case where users borrowed tokens before the market's borrow state index was set. + // Rewards the user with COMP accrued from the start of when borrower rewards were first + // set for the market. + borrowerIndex = compInitialIndex; + } + + // Calculate change in the cumulative sum of the COMP per borrowed unit accrued + Double memory deltaIndex = Double({mantissa: sub_(borrowIndex, borrowerIndex)}); + + uint borrowerAmount = div_(CToken(cToken).borrowBalanceStored(borrower), marketBorrowIndex); + + // Calculate COMP accrued: cTokenAmount * accruedPerBorrowedUnit + uint borrowerDelta = mul_(borrowerAmount, deltaIndex); + + uint borrowerAccrued = add_(compAccrued[borrower], borrowerDelta); + compAccrued[borrower] = borrowerAccrued; + + emit DistributedBorrowerComp(CToken(cToken), borrower, borrowerDelta, borrowIndex); + } + + /** + * @notice Calculate additional accrued COMP for a contributor since last accrual + * @param contributor The address to calculate contributor rewards for + */ + function updateContributorRewards(address contributor) public { + uint compSpeed = compContributorSpeeds[contributor]; + uint blockNumber = getBlockNumber(); + uint deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]); + if (deltaBlocks > 0 && compSpeed > 0) { + uint newAccrued = mul_(deltaBlocks, compSpeed); + uint contributorAccrued = add_(compAccrued[contributor], newAccrued); + + compAccrued[contributor] = contributorAccrued; + lastContributorBlock[contributor] = blockNumber; + } + } + + /** + * @notice Claim all the comp accrued by holder in all markets + * @param holder The address to claim COMP for + */ + function claimComp(address holder) public { + return claimComp(holder, allMarkets); + } + + /** + * @notice Claim all the comp accrued by holder in the specified markets + * @param holder The address to claim COMP for + * @param cTokens The list of markets to claim COMP in + */ + function claimComp(address holder, CToken[] memory cTokens) public { + address[] memory holders = new address[](1); + holders[0] = holder; + claimComp(holders, cTokens, true, true); + } + + /** + * @notice Claim all comp accrued by the holders + * @param holders The addresses to claim COMP for + * @param cTokens The list of markets to claim COMP in + * @param borrowers Whether or not to claim COMP earned by borrowing + * @param suppliers Whether or not to claim COMP earned by supplying + */ + function claimComp(address[] memory holders, CToken[] memory cTokens, bool borrowers, bool suppliers) public { + for (uint i = 0; i < cTokens.length; i++) { + CToken cToken = cTokens[i]; + require(markets[address(cToken)].isListed, "market must be listed"); + if (borrowers == true) { + Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); + updateCompBorrowIndex(address(cToken), borrowIndex); + for (uint j = 0; j < holders.length; j++) { + distributeBorrowerComp(address(cToken), holders[j], borrowIndex); + } + } + if (suppliers == true) { + updateCompSupplyIndex(address(cToken)); + for (uint j = 0; j < holders.length; j++) { + distributeSupplierComp(address(cToken), holders[j]); + } + } + } + for (uint j = 0; j < holders.length; j++) { + compAccrued[holders[j]] = grantCompInternal(holders[j], compAccrued[holders[j]]); + } + } + + /** + * @notice Transfer COMP to the user + * @dev Note: If there is not enough COMP, we do not perform the transfer all. + * @param user The address of the user to transfer COMP to + * @param amount The amount of COMP to (possibly) transfer + * @return The amount of COMP which was NOT transferred to the user + */ + function grantCompInternal(address user, uint amount) internal returns (uint) { + Comp comp = Comp(getCompAddress()); + uint compRemaining = comp.balanceOf(address(this)); + if (amount > 0 && amount <= compRemaining) { + comp.transfer(user, amount); + return 0; + } + return amount; + } + + /*** Comp Distribution Admin ***/ + + /** + * @notice Transfer COMP to the recipient + * @dev Note: If there is not enough COMP, we do not perform the transfer all. + * @param recipient The address of the recipient to transfer COMP to + * @param amount The amount of COMP to (possibly) transfer + */ + function _grantComp(address recipient, uint amount) public { + require(adminOrInitializing(), "only admin can grant comp"); + uint amountLeft = grantCompInternal(recipient, amount); + require(amountLeft == 0, "insufficient comp for grant"); + emit CompGranted(recipient, amount); + } + + /** + * @notice Set COMP borrow and supply speeds for the specified markets. + * @param cTokens The markets whose COMP speed to update. + * @param supplySpeeds New supply-side COMP speed for the corresponding market. + * @param borrowSpeeds New borrow-side COMP speed for the corresponding market. + */ + function _setCompSpeeds(CToken[] memory cTokens, uint[] memory supplySpeeds, uint[] memory borrowSpeeds) public { + require(adminOrInitializing(), "only admin can set comp speed"); + + uint numTokens = cTokens.length; + require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, "Comptroller::_setCompSpeeds invalid input"); + + for (uint i = 0; i < numTokens; ++i) { + setCompSpeedInternal(cTokens[i], supplySpeeds[i], borrowSpeeds[i]); + } + } + + /** + * @notice Set COMP speed for a single contributor + * @param contributor The contributor whose COMP speed to update + * @param compSpeed New COMP speed for contributor + */ + function _setContributorCompSpeed(address contributor, uint compSpeed) public { + require(adminOrInitializing(), "only admin can set comp speed"); + + // note that COMP speed could be set to 0 to halt liquidity rewards for a contributor + updateContributorRewards(contributor); + if (compSpeed == 0) { + // release storage + delete lastContributorBlock[contributor]; + } else { + lastContributorBlock[contributor] = getBlockNumber(); + } + compContributorSpeeds[contributor] = compSpeed; + + emit ContributorCompSpeedUpdated(contributor, compSpeed); + } + + /** + * @notice Return all of the markets + * @dev The automatic getter may be used to access an individual market. + * @return The list of market addresses + */ + function getAllMarkets() public view returns (CToken[] memory) { + return allMarkets; + } + + /** + * @notice Returns true if the given cToken market has been deprecated + * @dev All borrows in a deprecated cToken market can be immediately liquidated + * @param cToken The market to check if deprecated + */ + function isDeprecated(CToken cToken) public view returns (bool) { + return + markets[address(cToken)].collateralFactorMantissa == 0 && + borrowGuardianPaused[address(cToken)] == true && + cToken.reserveFactorMantissa() == 1e18 + ; + } + + function getBlockNumber() public view returns (uint) { + return block.number; + } + + /** + * @notice Return the address of the COMP token + * @return The address of COMP + */ + function getCompAddress() public view returns (address) { + return 0xc00e94Cb662C3520282E6f5717214004A7f26888; + } +} diff --git a/benchmark/ethereum/compound/contract/UNI.abi b/benchmark/ethereum/compound/contract/UNI.abi new file mode 100644 index 0000000..fccbe64 --- /dev/null +++ b/benchmark/ethereum/compound/contract/UNI.abi @@ -0,0 +1,306 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "tokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "tokenSymbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/UNI.bin b/benchmark/ethereum/compound/contract/UNI.bin new file mode 100644 index 0000000..3a4e914 --- /dev/null +++ b/benchmark/ethereum/compound/contract/UNI.bin @@ -0,0 +1 @@ +608060405234801562000010575f80fd5b5060405162001945380380620019458339818101604052810190620000369190620001eb565b81818160039081620000499190620004a5565b5080600490816200005b9190620004a5565b505050505062000589565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c7826200007f565b810181811067ffffffffffffffff82111715620000e957620000e86200008f565b5b80604052505050565b5f620000fd62000066565b90506200010b8282620000bc565b919050565b5f67ffffffffffffffff8211156200012d576200012c6200008f565b5b62000138826200007f565b9050602081019050919050565b5f5b838110156200016457808201518184015260208101905062000147565b5f8484015250505050565b5f620001856200017f8462000110565b620000f2565b905082815260208101848484011115620001a457620001a36200007b565b5b620001b184828562000145565b509392505050565b5f82601f830112620001d057620001cf62000077565b5b8151620001e28482602086016200016f565b91505092915050565b5f80604083850312156200020457620002036200006f565b5b5f83015167ffffffffffffffff81111562000224576200022362000073565b5b6200023285828601620001b9565b925050602083015167ffffffffffffffff81111562000256576200025562000073565b5b6200026485828601620001b9565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bd57607f821691505b602082108103620002d357620002d262000278565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003377fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002fa565b620003438683620002fa565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038d6200038762000381846200035b565b62000364565b6200035b565b9050919050565b5f819050919050565b620003a8836200036d565b620003c0620003b78262000394565b84845462000306565b825550505050565b5f90565b620003d6620003c8565b620003e38184846200039d565b505050565b5b818110156200040a57620003fe5f82620003cc565b600181019050620003e9565b5050565b601f82111562000459576200042381620002d9565b6200042e84620002eb565b810160208510156200043e578190505b620004566200044d85620002eb565b830182620003e8565b50505b505050565b5f82821c905092915050565b5f6200047b5f19846008026200045e565b1980831691505092915050565b5f6200049583836200046a565b9150826002028217905092915050565b620004b0826200026e565b67ffffffffffffffff811115620004cc57620004cb6200008f565b5b620004d88254620002a5565b620004e58282856200040e565b5f60209050601f8311600181146200051b575f841562000506578287015190505b62000512858262000488565b86555062000581565b601f1984166200052b86620002d9565b5f5b8281101562000554578489015182556001820191506020850194506020810190506200052d565b8683101562000574578489015162000570601f8916826200046a565b8355505b6001600288020188555050505b505050505050565b6113ae80620005975f395ff3fe608060405234801561000f575f80fd5b50600436106100b2575f3560e01c806340c10f191161006f57806340c10f19146101a057806370a08231146101bc57806395d89b41146101ec578063a457c2d71461020a578063a9059cbb1461023a578063dd62ed3e1461026a576100b2565b806306fdde03146100b6578063095ea7b3146100d457806318160ddd1461010457806323b872dd14610122578063313ce567146101525780633950935114610170575b5f80fd5b6100be61029a565b6040516100cb9190610c60565b60405180910390f35b6100ee60048036038101906100e99190610d11565b61032a565b6040516100fb9190610d69565b60405180910390f35b61010c61034c565b6040516101199190610d91565b60405180910390f35b61013c60048036038101906101379190610daa565b610355565b6040516101499190610d69565b60405180910390f35b61015a610383565b6040516101679190610e15565b60405180910390f35b61018a60048036038101906101859190610d11565b61038b565b6040516101979190610d69565b60405180910390f35b6101ba60048036038101906101b59190610d11565b6103c1565b005b6101d660048036038101906101d19190610e2e565b6103cf565b6040516101e39190610d91565b60405180910390f35b6101f4610414565b6040516102019190610c60565b60405180910390f35b610224600480360381019061021f9190610d11565b6104a4565b6040516102319190610d69565b60405180910390f35b610254600480360381019061024f9190610d11565b610519565b6040516102619190610d69565b60405180910390f35b610284600480360381019061027f9190610e59565b61053b565b6040516102919190610d91565b60405180910390f35b6060600380546102a990610ec4565b80601f01602080910402602001604051908101604052809291908181526020018280546102d590610ec4565b80156103205780601f106102f757610100808354040283529160200191610320565b820191905f5260205f20905b81548152906001019060200180831161030357829003601f168201915b5050505050905090565b5f806103346105bd565b90506103418185856105c4565b600191505092915050565b5f600254905090565b5f8061035f6105bd565b905061036c858285610787565b610377858585610812565b60019150509392505050565b5f6012905090565b5f806103956105bd565b90506103b68185856103a7858961053b565b6103b19190610f21565b6105c4565b600191505092915050565b6103cb8282610a7e565b5050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606004805461042390610ec4565b80601f016020809104026020016040519081016040528092919081815260200182805461044f90610ec4565b801561049a5780601f106104715761010080835404028352916020019161049a565b820191905f5260205f20905b81548152906001019060200180831161047d57829003601f168201915b5050505050905090565b5f806104ae6105bd565b90505f6104bb828661053b565b905083811015610500576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f790610fc4565b60405180910390fd5b61050d82868684036105c4565b60019250505092915050565b5f806105236105bd565b9050610530818585610812565b600191505092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062990611052565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036106a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610697906110e0565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161077a9190610d91565b60405180910390a3505050565b5f610792848461053b565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461080c57818110156107fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f590611148565b60405180910390fd5b61080b84848484036105c4565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610877906111d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036108ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e590611264565b60405180910390fd5b6108f9838383610bcc565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561097c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610973906112f2565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610a659190610d91565b60405180910390a3610a78848484610bd1565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae39061135a565b60405180910390fd5b610af75f8383610bcc565b8060025f828254610b089190610f21565b92505081905550805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508173ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610bb59190610d91565b60405180910390a3610bc85f8383610bd1565b5050565b505050565b505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015610c0d578082015181840152602081019050610bf2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610c3282610bd6565b610c3c8185610be0565b9350610c4c818560208601610bf0565b610c5581610c18565b840191505092915050565b5f6020820190508181035f830152610c788184610c28565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610cad82610c84565b9050919050565b610cbd81610ca3565b8114610cc7575f80fd5b50565b5f81359050610cd881610cb4565b92915050565b5f819050919050565b610cf081610cde565b8114610cfa575f80fd5b50565b5f81359050610d0b81610ce7565b92915050565b5f8060408385031215610d2757610d26610c80565b5b5f610d3485828601610cca565b9250506020610d4585828601610cfd565b9150509250929050565b5f8115159050919050565b610d6381610d4f565b82525050565b5f602082019050610d7c5f830184610d5a565b92915050565b610d8b81610cde565b82525050565b5f602082019050610da45f830184610d82565b92915050565b5f805f60608486031215610dc157610dc0610c80565b5b5f610dce86828701610cca565b9350506020610ddf86828701610cca565b9250506040610df086828701610cfd565b9150509250925092565b5f60ff82169050919050565b610e0f81610dfa565b82525050565b5f602082019050610e285f830184610e06565b92915050565b5f60208284031215610e4357610e42610c80565b5b5f610e5084828501610cca565b91505092915050565b5f8060408385031215610e6f57610e6e610c80565b5b5f610e7c85828601610cca565b9250506020610e8d85828601610cca565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610edb57607f821691505b602082108103610eee57610eed610e97565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610f2b82610cde565b9150610f3683610cde565b9250828201905080821115610f4e57610f4d610ef4565b5b92915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f775f8201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b5f610fae602583610be0565b9150610fb982610f54565b604082019050919050565b5f6020820190508181035f830152610fdb81610fa2565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f61103c602483610be0565b915061104782610fe2565b604082019050919050565b5f6020820190508181035f83015261106981611030565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6110ca602283610be0565b91506110d582611070565b604082019050919050565b5f6020820190508181035f8301526110f7816110be565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000005f82015250565b5f611132601d83610be0565b915061113d826110fe565b602082019050919050565b5f6020820190508181035f83015261115f81611126565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f6111c0602583610be0565b91506111cb82611166565b604082019050919050565b5f6020820190508181035f8301526111ed816111b4565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f61124e602383610be0565b9150611259826111f4565b604082019050919050565b5f6020820190508181035f83015261127b81611242565b9050919050565b7f45524332303a207472616e7366657220616d6f756e74206578636565647320625f8201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b5f6112dc602683610be0565b91506112e782611282565b604082019050919050565b5f6020820190508181035f830152611309816112d0565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f2061646472657373005f82015250565b5f611344601f83610be0565b915061134f82611310565b602082019050919050565b5f6020820190508181035f83015261137181611338565b905091905056fea26469706673582212206339baff4db6e4493ef81f2741cd387b86434d904279d1348383d6565cbb957764736f6c63430008150033 \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/UNI.sol b/benchmark/ethereum/compound/contract/UNI.sol new file mode 100644 index 0000000..80555b3 --- /dev/null +++ b/benchmark/ethereum/compound/contract/UNI.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.8.0; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract UNI is ERC20 { + + constructor(string memory tokenName,string memory tokenSymbol) ERC20(tokenName, tokenSymbol) { + } + + function mint(address _address, uint _amount) public { + _mint(_address, _amount); + } + +} \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/USDC.abi b/benchmark/ethereum/compound/contract/USDC.abi new file mode 100644 index 0000000..fccbe64 --- /dev/null +++ b/benchmark/ethereum/compound/contract/USDC.abi @@ -0,0 +1,306 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "tokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "tokenSymbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/USDC.bin b/benchmark/ethereum/compound/contract/USDC.bin new file mode 100644 index 0000000..3a4e914 --- /dev/null +++ b/benchmark/ethereum/compound/contract/USDC.bin @@ -0,0 +1 @@ +608060405234801562000010575f80fd5b5060405162001945380380620019458339818101604052810190620000369190620001eb565b81818160039081620000499190620004a5565b5080600490816200005b9190620004a5565b505050505062000589565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c7826200007f565b810181811067ffffffffffffffff82111715620000e957620000e86200008f565b5b80604052505050565b5f620000fd62000066565b90506200010b8282620000bc565b919050565b5f67ffffffffffffffff8211156200012d576200012c6200008f565b5b62000138826200007f565b9050602081019050919050565b5f5b838110156200016457808201518184015260208101905062000147565b5f8484015250505050565b5f620001856200017f8462000110565b620000f2565b905082815260208101848484011115620001a457620001a36200007b565b5b620001b184828562000145565b509392505050565b5f82601f830112620001d057620001cf62000077565b5b8151620001e28482602086016200016f565b91505092915050565b5f80604083850312156200020457620002036200006f565b5b5f83015167ffffffffffffffff81111562000224576200022362000073565b5b6200023285828601620001b9565b925050602083015167ffffffffffffffff81111562000256576200025562000073565b5b6200026485828601620001b9565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bd57607f821691505b602082108103620002d357620002d262000278565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003377fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002fa565b620003438683620002fa565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038d6200038762000381846200035b565b62000364565b6200035b565b9050919050565b5f819050919050565b620003a8836200036d565b620003c0620003b78262000394565b84845462000306565b825550505050565b5f90565b620003d6620003c8565b620003e38184846200039d565b505050565b5b818110156200040a57620003fe5f82620003cc565b600181019050620003e9565b5050565b601f82111562000459576200042381620002d9565b6200042e84620002eb565b810160208510156200043e578190505b620004566200044d85620002eb565b830182620003e8565b50505b505050565b5f82821c905092915050565b5f6200047b5f19846008026200045e565b1980831691505092915050565b5f6200049583836200046a565b9150826002028217905092915050565b620004b0826200026e565b67ffffffffffffffff811115620004cc57620004cb6200008f565b5b620004d88254620002a5565b620004e58282856200040e565b5f60209050601f8311600181146200051b575f841562000506578287015190505b62000512858262000488565b86555062000581565b601f1984166200052b86620002d9565b5f5b8281101562000554578489015182556001820191506020850194506020810190506200052d565b8683101562000574578489015162000570601f8916826200046a565b8355505b6001600288020188555050505b505050505050565b6113ae80620005975f395ff3fe608060405234801561000f575f80fd5b50600436106100b2575f3560e01c806340c10f191161006f57806340c10f19146101a057806370a08231146101bc57806395d89b41146101ec578063a457c2d71461020a578063a9059cbb1461023a578063dd62ed3e1461026a576100b2565b806306fdde03146100b6578063095ea7b3146100d457806318160ddd1461010457806323b872dd14610122578063313ce567146101525780633950935114610170575b5f80fd5b6100be61029a565b6040516100cb9190610c60565b60405180910390f35b6100ee60048036038101906100e99190610d11565b61032a565b6040516100fb9190610d69565b60405180910390f35b61010c61034c565b6040516101199190610d91565b60405180910390f35b61013c60048036038101906101379190610daa565b610355565b6040516101499190610d69565b60405180910390f35b61015a610383565b6040516101679190610e15565b60405180910390f35b61018a60048036038101906101859190610d11565b61038b565b6040516101979190610d69565b60405180910390f35b6101ba60048036038101906101b59190610d11565b6103c1565b005b6101d660048036038101906101d19190610e2e565b6103cf565b6040516101e39190610d91565b60405180910390f35b6101f4610414565b6040516102019190610c60565b60405180910390f35b610224600480360381019061021f9190610d11565b6104a4565b6040516102319190610d69565b60405180910390f35b610254600480360381019061024f9190610d11565b610519565b6040516102619190610d69565b60405180910390f35b610284600480360381019061027f9190610e59565b61053b565b6040516102919190610d91565b60405180910390f35b6060600380546102a990610ec4565b80601f01602080910402602001604051908101604052809291908181526020018280546102d590610ec4565b80156103205780601f106102f757610100808354040283529160200191610320565b820191905f5260205f20905b81548152906001019060200180831161030357829003601f168201915b5050505050905090565b5f806103346105bd565b90506103418185856105c4565b600191505092915050565b5f600254905090565b5f8061035f6105bd565b905061036c858285610787565b610377858585610812565b60019150509392505050565b5f6012905090565b5f806103956105bd565b90506103b68185856103a7858961053b565b6103b19190610f21565b6105c4565b600191505092915050565b6103cb8282610a7e565b5050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606004805461042390610ec4565b80601f016020809104026020016040519081016040528092919081815260200182805461044f90610ec4565b801561049a5780601f106104715761010080835404028352916020019161049a565b820191905f5260205f20905b81548152906001019060200180831161047d57829003601f168201915b5050505050905090565b5f806104ae6105bd565b90505f6104bb828661053b565b905083811015610500576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f790610fc4565b60405180910390fd5b61050d82868684036105c4565b60019250505092915050565b5f806105236105bd565b9050610530818585610812565b600191505092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062990611052565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036106a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610697906110e0565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161077a9190610d91565b60405180910390a3505050565b5f610792848461053b565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461080c57818110156107fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f590611148565b60405180910390fd5b61080b84848484036105c4565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610877906111d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036108ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e590611264565b60405180910390fd5b6108f9838383610bcc565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561097c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610973906112f2565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610a659190610d91565b60405180910390a3610a78848484610bd1565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae39061135a565b60405180910390fd5b610af75f8383610bcc565b8060025f828254610b089190610f21565b92505081905550805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508173ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610bb59190610d91565b60405180910390a3610bc85f8383610bd1565b5050565b505050565b505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015610c0d578082015181840152602081019050610bf2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610c3282610bd6565b610c3c8185610be0565b9350610c4c818560208601610bf0565b610c5581610c18565b840191505092915050565b5f6020820190508181035f830152610c788184610c28565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610cad82610c84565b9050919050565b610cbd81610ca3565b8114610cc7575f80fd5b50565b5f81359050610cd881610cb4565b92915050565b5f819050919050565b610cf081610cde565b8114610cfa575f80fd5b50565b5f81359050610d0b81610ce7565b92915050565b5f8060408385031215610d2757610d26610c80565b5b5f610d3485828601610cca565b9250506020610d4585828601610cfd565b9150509250929050565b5f8115159050919050565b610d6381610d4f565b82525050565b5f602082019050610d7c5f830184610d5a565b92915050565b610d8b81610cde565b82525050565b5f602082019050610da45f830184610d82565b92915050565b5f805f60608486031215610dc157610dc0610c80565b5b5f610dce86828701610cca565b9350506020610ddf86828701610cca565b9250506040610df086828701610cfd565b9150509250925092565b5f60ff82169050919050565b610e0f81610dfa565b82525050565b5f602082019050610e285f830184610e06565b92915050565b5f60208284031215610e4357610e42610c80565b5b5f610e5084828501610cca565b91505092915050565b5f8060408385031215610e6f57610e6e610c80565b5b5f610e7c85828601610cca565b9250506020610e8d85828601610cca565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610edb57607f821691505b602082108103610eee57610eed610e97565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610f2b82610cde565b9150610f3683610cde565b9250828201905080821115610f4e57610f4d610ef4565b5b92915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f775f8201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b5f610fae602583610be0565b9150610fb982610f54565b604082019050919050565b5f6020820190508181035f830152610fdb81610fa2565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f61103c602483610be0565b915061104782610fe2565b604082019050919050565b5f6020820190508181035f83015261106981611030565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6110ca602283610be0565b91506110d582611070565b604082019050919050565b5f6020820190508181035f8301526110f7816110be565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000005f82015250565b5f611132601d83610be0565b915061113d826110fe565b602082019050919050565b5f6020820190508181035f83015261115f81611126565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f6111c0602583610be0565b91506111cb82611166565b604082019050919050565b5f6020820190508181035f8301526111ed816111b4565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f61124e602383610be0565b9150611259826111f4565b604082019050919050565b5f6020820190508181035f83015261127b81611242565b9050919050565b7f45524332303a207472616e7366657220616d6f756e74206578636565647320625f8201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b5f6112dc602683610be0565b91506112e782611282565b604082019050919050565b5f6020820190508181035f830152611309816112d0565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f2061646472657373005f82015250565b5f611344601f83610be0565b915061134f82611310565b602082019050919050565b5f6020820190508181035f83015261137181611338565b905091905056fea26469706673582212206339baff4db6e4493ef81f2741cd387b86434d904279d1348383d6565cbb957764736f6c63430008150033 \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/USDC.sol b/benchmark/ethereum/compound/contract/USDC.sol new file mode 100644 index 0000000..428a0e2 --- /dev/null +++ b/benchmark/ethereum/compound/contract/USDC.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.8.0; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract USDC is ERC20 { + + constructor(string memory tokenName,string memory tokenSymbol) ERC20(tokenName, tokenSymbol) { + } + + function mint(address _address, uint _amount) public { + _mint(_address, _amount); + } + +} \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/deploy.abi b/benchmark/ethereum/compound/contract/deploy.abi new file mode 100644 index 0000000..4a6b1a7 --- /dev/null +++ b/benchmark/ethereum/compound/contract/deploy.abi @@ -0,0 +1,158 @@ +[ + { + "inputs": [], + "name": "deploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "Deployed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_salt", + "type": "string" + } + ], + "name": "setSalt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ComptrollerAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CUNIAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CUSDCAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "JumpRateModelAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LegacyJumpRateModelAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PriceOracleAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "salt", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNIAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDCAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/deploy.bin b/benchmark/ethereum/compound/contract/deploy.bin new file mode 100644 index 0000000..414209a --- /dev/null +++ b/benchmark/ethereum/compound/contract/deploy.bin @@ -0,0 +1 @@ +60806040526040518060400160405280600781526020017f64656661756c74000000000000000000000000000000000000000000000000008152505f90816200004991906200128c565b5034801562000056575f80fd5b50620000676200006d60201b60201c565b62001e92565b6200007d620000ff60201b60201c565b6200008d620002b260201b60201c565b6200009d6200040060201b60201c565b620000ad6200054160201b60201c565b620000bd6200078760201b60201c565b620000cd62000a5360201b60201c565b620000dd62000b1660201b60201c565b620000ed62000c9a60201b60201c565b620000fd62000e0b60201b60201c565b565b5f60405180610ca00160405280610c6281526020016201f682610c6291399050620001a86040518060400160405280600581526020017f6572633230000000000000000000000000000000000000000000000000000000815250826040516020016200016b90620013ce565b6040516020818303038152906040526040516020016200018d92919062001477565b60405160208183030381529060405262000fa360201b60201c565b60015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620002706040518060400160405280600581526020017f6572633230000000000000000000000000000000000000000000000000000000815250826040516020016200023390620014ec565b6040516020818303038152906040526040516020016200025592919062001477565b60405160208183030381529060405262000fa360201b60201c565b60025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60405180615b600160405280615b30815260200162018646615b30913990506200035d6040518060400160405280600b81526020017f436f6d7074726f6c6c657200000000000000000000000000000000000000000081525082306040516020016200032091906200159e565b6040516020818303038152906040526040516020016200034292919062001477565b60405160208183030381529060405262000fa360201b60201c565b60055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f6040518061060001604052806105ce8152602001620180786105ce913990506200049e6040518060400160405280601181526020017f53696d706c6550726963654f7261636c65000000000000000000000000000000815250826040516020016040516020818303038152906040526040516020016200048392919062001477565b60405160208183030381529060405262000fa360201b60201c565b60065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60405180610aa00160405280610a7281526020016201ec10610a72913990505f60405180610ac00160405280610a9a81526020016201e176610a9a91399050620006476040518060400160405280600f81526020017f4a756d70526174654d6f64656c563200000000000000000000000000000000008152508366470de4df82000067027f7d0bdb920000673782dace9d900000670b1a2bc2ec50000073c7f999b83af6df9e67d0a37ee7e900bf38b3d0136040516020016200060a95949392919062001706565b6040516020818303038152906040526040516020016200062c92919062001477565b60405160208183030381529060405262000fa360201b60201c565b60085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620007446040518060400160405280601581526020017f4c65676163794a756d70526174654d6f64656c56320000000000000000000000815250825f668e1bc9bf040000670f207539952d0000670b1a2bc2ec50000073c7f999b83af6df9e67d0a37ee7e900bf38b3d0136040516020016200070795949392919062001830565b6040516020818303038152906040526040516020016200072992919062001477565b60405160208183030381529060405262000fa360201b60201c565b60075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b5f60405180615e200160405280615dfb81526020016201227d615dfb91399050620008bf6040518060400160405280600f81526020017f434572633230496d6d757461626c6500000000000000000000000000000000008152508260015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166aa56fa5b99019a5c8000000600873c7f999b83af6df9e67d0a37ee7e900bf38b3d013604051602001620008829695949392919062001971565b604051602081830303815290604052604051602001620008a492919062001477565b60405160208183030381529060405262000fa360201b60201c565b60035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000a116040518060400160405280600f81526020017f434572633230496d6d757461626c6500000000000000000000000000000000008152508260025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1665b5e620f48000600873c7f999b83af6df9e67d0a37ee7e900bf38b3d013604051602001620009d49695949392919062001aa7565b604051602081830303815290604052604051602001620009f692919062001477565b60405160208183030381529060405262000fa360201b60201c565b60045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166355ee1fe160065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162000ad0919062001b3d565b6020604051808303815f875af115801562000aed573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000b13919062001b8b565b50565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a76b3fda60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162000b93919062001b3d565b6020604051808303815f875af115801562000bb0573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000bd6919062001b8b565b5060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a76b3fda60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162000c54919062001b3d565b6020604051808303815f875af115801562000c71573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000c97919062001b8b565b50565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663127ffda060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1668015b42a8bad41dc0006040518363ffffffff1660e01b815260040162000d2292919062001bfc565b5f604051808303815f87803b15801562000d3a575f80fd5b505af115801562000d4d573d5f803e3d5ffd5b50505050600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663127ffda060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166907907ac7d430a07380006040518363ffffffff1660e01b815260040162000dda92919062001c68565b5f604051808303815f87803b15801562000df2575f80fd5b505af115801562000e05573d5f803e3d5ffd5b50505050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4028eee60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16670b1a2bc2ec5000006040518363ffffffff1660e01b815260040162000e9292919062001ccb565b6020604051808303815f875af115801562000eaf573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000ed5919062001b8b565b5060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4028eee60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16670853a0d2313c00006040518363ffffffff1660e01b815260040162000f5d92919062001d37565b6020604051808303815f875af115801562000f7a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000fa0919062001b8b565b50565b5f805f60405160200162000fb8919062001df8565b604051602081830303815290604052805190602001209050808351602085015ff59150813b62000fe6575f80fd5b7f2009540abb31a9afba343443e75c244a4fc7cf4348628c3dcfce844220e5eaf384836040516200101992919062001e60565b60405180910390a15092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620010a457607f821691505b602082108103620010ba57620010b96200105f565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200111e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620010e1565b6200112a8683620010e1565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620011746200116e620011688462001142565b6200114b565b62001142565b9050919050565b5f819050919050565b6200118f8362001154565b620011a76200119e826200117b565b848454620010ed565b825550505050565b5f90565b620011bd620011af565b620011ca81848462001184565b505050565b5b81811015620011f157620011e55f82620011b3565b600181019050620011d0565b5050565b601f82111562001240576200120a81620010c0565b6200121584620010d2565b8101602085101562001225578190505b6200123d6200123485620010d2565b830182620011cf565b50505b505050565b5f82821c905092915050565b5f620012625f198460080262001245565b1980831691505092915050565b5f6200127c838362001251565b9150826002028217905092915050565b620012978262001028565b67ffffffffffffffff811115620012b357620012b262001032565b5b620012bf82546200108c565b620012cc828285620011f5565b5f60209050601f83116001811462001302575f8415620012ed578287015190505b620012f985826200126f565b86555062001368565b601f1984166200131286620010c0565b5f5b828110156200133b5784890151825560018201915060208501945060208101905062001314565b868310156200135b578489015162001357601f89168262001251565b8355505b6001600288020188555050505b505050505050565b5f82825260208201905092915050565b7f554e4900000000000000000000000000000000000000000000000000000000005f82015250565b5f620013b660038362001370565b9150620013c38262001380565b602082019050919050565b5f6040820190508181035f830152620013e781620013a8565b90508181036020830152620013fc81620013a8565b9050919050565b5f81519050919050565b5f81905092915050565b5f5b838110156200143657808201518184015260208101905062001419565b5f8484015250505050565b5f6200144d8262001403565b6200145981856200140d565b93506200146b81856020860162001417565b80840191505092915050565b5f62001484828562001441565b915062001492828462001441565b91508190509392505050565b7f55534443000000000000000000000000000000000000000000000000000000005f82015250565b5f620014d460048362001370565b9150620014e1826200149e565b602082019050919050565b5f6040820190508181035f8301526200150581620014c6565b905081810360208301526200151a81620014c6565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620015606200155a620015548462001521565b6200114b565b62001521565b9050919050565b5f620015738262001540565b9050919050565b5f620015868262001567565b9050919050565b62001598816200157a565b82525050565b5f602082019050620015b35f8301846200158d565b92915050565b5f819050919050565b5f66ffffffffffffff82169050919050565b5f620015f4620015ee620015e884620015b9565b6200114b565b620015c2565b9050919050565b6200160681620015d4565b82525050565b5f819050919050565b5f67ffffffffffffffff82169050919050565b5f62001648620016426200163c846200160c565b6200114b565b62001615565b9050919050565b6200165a8162001628565b82525050565b5f819050919050565b5f62001689620016836200167d8462001660565b6200114b565b62001615565b9050919050565b6200169b8162001669565b82525050565b5f819050919050565b5f620016ca620016c4620016be84620016a1565b6200114b565b62001615565b9050919050565b620016dc81620016aa565b82525050565b5f620016ee8262001521565b9050919050565b6200170081620016e2565b82525050565b5f60a0820190506200171b5f830188620015fb565b6200172a60208301876200164f565b62001739604083018662001690565b620017486060830185620016d1565b620017576080830184620016f5565b9695505050505050565b5f819050919050565b5f60ff82169050919050565b5f62001796620017906200178a8462001761565b6200114b565b6200176a565b9050919050565b620017a88162001776565b82525050565b5f819050919050565b5f620017d7620017d1620017cb84620017ae565b6200114b565b620015c2565b9050919050565b620017e981620017b7565b82525050565b5f819050919050565b5f62001818620018126200180c84620017ef565b6200114b565b62001615565b9050919050565b6200182a81620017f8565b82525050565b5f60a082019050620018455f8301886200179d565b620018546020830187620017de565b6200186360408301866200181f565b620018726060830185620016d1565b620018816080830184620016f5565b9695505050505050565b5f819050919050565b5f6affffffffffffffffffffff82169050919050565b5f620018ca620018c4620018be846200188b565b6200114b565b62001894565b9050919050565b620018dc81620018aa565b82525050565b7f63554e49000000000000000000000000000000000000000000000000000000005f82015250565b5f6200191860048362001370565b91506200192582620018e2565b602082019050919050565b5f819050919050565b5f62001959620019536200194d8462001930565b6200114b565b6200176a565b9050919050565b6200196b8162001939565b82525050565b5f61010082019050620019875f830189620016f5565b620019966020830188620016f5565b620019a56040830187620016f5565b620019b46060830186620018d1565b8181036080830152620019c7816200190a565b905081810360a0830152620019dc816200190a565b9050620019ed60c083018562001960565b620019fc60e0830184620016f5565b979650505050505050565b5f819050919050565b5f65ffffffffffff82169050919050565b5f62001a4162001a3b62001a358462001a07565b6200114b565b62001a10565b9050919050565b62001a538162001a21565b82525050565b7f63555344430000000000000000000000000000000000000000000000000000005f82015250565b5f62001a8f60058362001370565b915062001a9c8262001a59565b602082019050919050565b5f6101008201905062001abd5f830189620016f5565b62001acc6020830188620016f5565b62001adb6040830187620016f5565b62001aea606083018662001a48565b818103608083015262001afd8162001a81565b905081810360a083015262001b128162001a81565b905062001b2360c083018562001960565b62001b3260e0830184620016f5565b979650505050505050565b5f60208201905062001b525f830184620016f5565b92915050565b5f80fd5b62001b678162001142565b811462001b72575f80fd5b50565b5f8151905062001b858162001b5c565b92915050565b5f6020828403121562001ba35762001ba262001b58565b5b5f62001bb28482850162001b75565b91505092915050565b5f819050919050565b5f62001be462001bde62001bd88462001bbb565b6200114b565b62001142565b9050919050565b62001bf68162001bc4565b82525050565b5f60408201905062001c115f830185620016f5565b62001c20602083018462001beb565b9392505050565b5f819050919050565b5f62001c5062001c4a62001c448462001c27565b6200114b565b62001142565b9050919050565b62001c628162001c30565b82525050565b5f60408201905062001c7d5f830185620016f5565b62001c8c602083018462001c57565b9392505050565b5f62001cb362001cad62001ca784620016a1565b6200114b565b62001142565b9050919050565b62001cc58162001c93565b82525050565b5f60408201905062001ce05f830185620016f5565b62001cef602083018462001cba565b9392505050565b5f819050919050565b5f62001d1f62001d1962001d138462001cf6565b6200114b565b62001142565b9050919050565b62001d318162001cff565b82525050565b5f60408201905062001d4c5f830185620016f5565b62001d5b602083018462001d26565b9392505050565b5f81905092915050565b5f815462001d7a816200108c565b62001d86818662001d62565b9450600182165f811462001da3576001811462001db95762001def565b60ff198316865281151582028601935062001def565b62001dc485620010c0565b5f5b8381101562001de75781548189015260018201915060208101905062001dc6565b838801955050505b50505092915050565b5f62001e05828462001d6c565b915081905092915050565b5f601f19601f8301169050919050565b5f62001e2c8262001028565b62001e38818562001370565b935062001e4a81856020860162001417565b62001e558162001e10565b840191505092915050565b5f6040820190508181035f83015262001e7a818562001e20565b905062001e8b6020830184620016f5565b9392505050565b620103dc8062001ea15f395ff3fe608060405234801562000010575f80fd5b5060043610620000b6575f3560e01c8063c9fd01271162000079578063c9fd0127146200014e578063cb6d9e77146200016e578063e356578a1462000190578063e6d4d97114620001b2578063f6951c9414620001d4578063fdcd7f4c14620001f657620000b6565b80636255cfb314620000ba57806370884fc414620000dc578063775c300c14620000fe5780637cafbc0d146200010a578063bfa0b133146200012c575b5f80fd5b620000c462000218565b604051620000d391906200137f565b60405180910390f35b620000e66200023d565b604051620000f591906200137f565b60405180910390f35b6200010862000262565b005b62000114620002be565b6040516200012391906200137f565b60405180910390f35b62000136620002e3565b6040516200014591906200142e565b60405180910390f35b6200016c6004803603810190620001669190620015a9565b62000376565b005b620001786200038a565b6040516200018791906200137f565b60405180910390f35b6200019a620003af565b604051620001a991906200137f565b60405180910390f35b620001bc620003d4565b604051620001cb91906200137f565b60405180910390f35b620001de620003f9565b604051620001ed91906200137f565b60405180910390f35b620002006200041e565b6040516200020f91906200137f565b60405180910390f35b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6200026c62000443565b62000276620005ea565b6200028062000732565b6200028a6200086d565b6200029462000aa7565b6200029e62000d67565b620002a862000e2a565b620002b262000fae565b620002bc6200111f565b565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054620002f19062001625565b80601f01602080910402602001604051908101604052809291908181526020018280546200031f9062001625565b80156200036e5780601f1062000344576101008083540402835291602001916200036e565b820191905f5260205f20905b8154815290600101906020018083116200035057829003601f168201915b505050505081565b805f908162000386919062001825565b5050565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60405180610ca00160405280610c6281526020016200f745610c6291399050620004e66040518060400160405280600581526020017f657263323000000000000000000000000000000000000000000000000000000081525082604051602001620004af9062001957565b604051602081830303815290604052604051602001620004d1929190620019d6565b604051602081830303815290604052620012b7565b60015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620005a86040518060400160405280600581526020017f657263323000000000000000000000000000000000000000000000000000000081525082604051602001620005719062001a4b565b60405160208183030381529060405260405160200162000593929190620019d6565b604051602081830303815290604052620012b7565b60025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60405180615b600160405280615b30815260200162008709615b30913990506200068f6040518060400160405280600b81526020017f436f6d7074726f6c6c6572000000000000000000000000000000000000000000815250823060405160200162000658919062001ade565b6040516020818303038152906040526040516020016200067a929190620019d6565b604051602081830303815290604052620012b7565b60055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f6040518061060001604052806105ce81526020016200813b6105ce91399050620007ca6040518060400160405280601181526020017f53696d706c6550726963654f7261636c6500000000000000000000000000000081525082604051602001604051602081830303815290604052604051602001620007b5929190620019d6565b604051602081830303815290604052620012b7565b60065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60405180610aa00160405280610a7281526020016200ecd3610a72913990505f60405180610ac00160405280610a9a81526020016200e239610a9a913990506200096d6040518060400160405280600f81526020017f4a756d70526174654d6f64656c563200000000000000000000000000000000008152508366470de4df82000067027f7d0bdb920000673782dace9d900000670b1a2bc2ec50000073c7f999b83af6df9e67d0a37ee7e900bf38b3d0136040516020016200093695949392919062001c22565b60405160208183030381529060405260405160200162000958929190620019d6565b604051602081830303815290604052620012b7565b60085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000a646040518060400160405280601581526020017f4c65676163794a756d70526174654d6f64656c56320000000000000000000000815250825f668e1bc9bf040000670f207539952d0000670b1a2bc2ec50000073c7f999b83af6df9e67d0a37ee7e900bf38b3d01360405160200162000a2d95949392919062001d4c565b60405160208183030381529060405260405160200162000a4f929190620019d6565b604051602081830303815290604052620012b7565b60075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b5f60405180615e200160405280615dfb815260200162002340615dfb9139905062000bd96040518060400160405280600f81526020017f434572633230496d6d757461626c6500000000000000000000000000000000008152508260015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166aa56fa5b99019a5c8000000600873c7f999b83af6df9e67d0a37ee7e900bf38b3d01360405160200162000ba29695949392919062001e8d565b60405160208183030381529060405260405160200162000bc4929190620019d6565b604051602081830303815290604052620012b7565b60035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000d256040518060400160405280600f81526020017f434572633230496d6d757461626c6500000000000000000000000000000000008152508260025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1665b5e620f48000600873c7f999b83af6df9e67d0a37ee7e900bf38b3d01360405160200162000cee9695949392919062001fc3565b60405160208183030381529060405260405160200162000d10929190620019d6565b604051602081830303815290604052620012b7565b60045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166355ee1fe160065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162000de491906200137f565b6020604051808303815f875af115801562000e01573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000e27919062002088565b50565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a76b3fda60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162000ea791906200137f565b6020604051808303815f875af115801562000ec4573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000eea919062002088565b5060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a76b3fda60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162000f6891906200137f565b6020604051808303815f875af115801562000f85573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000fab919062002088565b50565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663127ffda060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1668015b42a8bad41dc0006040518363ffffffff1660e01b815260040162001036929190620020f9565b5f604051808303815f87803b1580156200104e575f80fd5b505af115801562001061573d5f803e3d5ffd5b50505050600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663127ffda060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166907907ac7d430a07380006040518363ffffffff1660e01b8152600401620010ee92919062002165565b5f604051808303815f87803b15801562001106575f80fd5b505af115801562001119573d5f803e3d5ffd5b50505050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4028eee60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16670b1a2bc2ec5000006040518363ffffffff1660e01b8152600401620011a6929190620021c8565b6020604051808303815f875af1158015620011c3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620011e9919062002088565b5060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4028eee60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16670853a0d2313c00006040518363ffffffff1660e01b81526004016200127192919062002234565b6020604051808303815f875af11580156200128e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620012b4919062002088565b50565b5f805f604051602001620012cc9190620022f5565b604051602081830303815290604052805190602001209050808351602085015ff59150813b620012fa575f80fd5b7f2009540abb31a9afba343443e75c244a4fc7cf4348628c3dcfce844220e5eaf384836040516200132d9291906200230d565b60405180910390a15092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62001367826200133c565b9050919050565b62001379816200135b565b82525050565b5f602082019050620013945f8301846200136e565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015620013d3578082015181840152602081019050620013b6565b5f8484015250505050565b5f601f19601f8301169050919050565b5f620013fa826200139a565b620014068185620013a4565b935062001418818560208601620013b4565b6200142381620013de565b840191505092915050565b5f6020820190508181035f830152620014488184620013ee565b905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620014a182620013de565b810181811067ffffffffffffffff82111715620014c357620014c262001469565b5b80604052505050565b5f620014d762001450565b9050620014e5828262001496565b919050565b5f67ffffffffffffffff82111562001507576200150662001469565b5b6200151282620013de565b9050602081019050919050565b828183375f83830152505050565b5f620015436200153d84620014ea565b620014cc565b90508281526020810184848401111562001562576200156162001465565b5b6200156f8482856200151f565b509392505050565b5f82601f8301126200158e576200158d62001461565b5b8135620015a08482602086016200152d565b91505092915050565b5f60208284031215620015c157620015c062001459565b5b5f82013567ffffffffffffffff811115620015e157620015e06200145d565b5b620015ef8482850162001577565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200163d57607f821691505b602082108103620016535762001652620015f8565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620016b77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200167a565b620016c386836200167a565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200170d620017076200170184620016db565b620016e4565b620016db565b9050919050565b5f819050919050565b6200172883620016ed565b62001740620017378262001714565b84845462001686565b825550505050565b5f90565b6200175662001748565b620017638184846200171d565b505050565b5b818110156200178a576200177e5f826200174c565b60018101905062001769565b5050565b601f821115620017d957620017a38162001659565b620017ae846200166b565b81016020851015620017be578190505b620017d6620017cd856200166b565b83018262001768565b50505b505050565b5f82821c905092915050565b5f620017fb5f1984600802620017de565b1980831691505092915050565b5f620018158383620017ea565b9150826002028217905092915050565b62001830826200139a565b67ffffffffffffffff8111156200184c576200184b62001469565b5b62001858825462001625565b620018658282856200178e565b5f60209050601f8311600181146200189b575f841562001886578287015190505b62001892858262001808565b86555062001901565b601f198416620018ab8662001659565b5f5b82811015620018d457848901518255600182019150602085019450602081019050620018ad565b86831015620018f45784890151620018f0601f891682620017ea565b8355505b6001600288020188555050505b505050505050565b7f554e4900000000000000000000000000000000000000000000000000000000005f82015250565b5f6200193f600383620013a4565b91506200194c8262001909565b602082019050919050565b5f6040820190508181035f830152620019708162001931565b90508181036020830152620019858162001931565b9050919050565b5f81519050919050565b5f81905092915050565b5f620019ac826200198c565b620019b8818562001996565b9350620019ca818560208601620013b4565b80840191505092915050565b5f620019e38285620019a0565b9150620019f18284620019a0565b91508190509392505050565b7f55534443000000000000000000000000000000000000000000000000000000005f82015250565b5f62001a33600483620013a4565b915062001a4082620019fd565b602082019050919050565b5f6040820190508181035f83015262001a648162001a25565b9050818103602083015262001a798162001a25565b9050919050565b5f62001aa062001a9a62001a94846200133c565b620016e4565b6200133c565b9050919050565b5f62001ab38262001a80565b9050919050565b5f62001ac68262001aa7565b9050919050565b62001ad88162001aba565b82525050565b5f60208201905062001af35f83018462001acd565b92915050565b5f819050919050565b5f66ffffffffffffff82169050919050565b5f62001b3462001b2e62001b288462001af9565b620016e4565b62001b02565b9050919050565b62001b468162001b14565b82525050565b5f819050919050565b5f67ffffffffffffffff82169050919050565b5f62001b8862001b8262001b7c8462001b4c565b620016e4565b62001b55565b9050919050565b62001b9a8162001b68565b82525050565b5f819050919050565b5f62001bc962001bc362001bbd8462001ba0565b620016e4565b62001b55565b9050919050565b62001bdb8162001ba9565b82525050565b5f819050919050565b5f62001c0a62001c0462001bfe8462001be1565b620016e4565b62001b55565b9050919050565b62001c1c8162001bea565b82525050565b5f60a08201905062001c375f83018862001b3b565b62001c46602083018762001b8f565b62001c55604083018662001bd0565b62001c64606083018562001c11565b62001c7360808301846200136e565b9695505050505050565b5f819050919050565b5f60ff82169050919050565b5f62001cb262001cac62001ca68462001c7d565b620016e4565b62001c86565b9050919050565b62001cc48162001c92565b82525050565b5f819050919050565b5f62001cf362001ced62001ce78462001cca565b620016e4565b62001b02565b9050919050565b62001d058162001cd3565b82525050565b5f819050919050565b5f62001d3462001d2e62001d288462001d0b565b620016e4565b62001b55565b9050919050565b62001d468162001d14565b82525050565b5f60a08201905062001d615f83018862001cb9565b62001d70602083018762001cfa565b62001d7f604083018662001d3b565b62001d8e606083018562001c11565b62001d9d60808301846200136e565b9695505050505050565b5f819050919050565b5f6affffffffffffffffffffff82169050919050565b5f62001de662001de062001dda8462001da7565b620016e4565b62001db0565b9050919050565b62001df88162001dc6565b82525050565b7f63554e49000000000000000000000000000000000000000000000000000000005f82015250565b5f62001e34600483620013a4565b915062001e418262001dfe565b602082019050919050565b5f819050919050565b5f62001e7562001e6f62001e698462001e4c565b620016e4565b62001c86565b9050919050565b62001e878162001e55565b82525050565b5f6101008201905062001ea35f8301896200136e565b62001eb260208301886200136e565b62001ec160408301876200136e565b62001ed0606083018662001ded565b818103608083015262001ee38162001e26565b905081810360a083015262001ef88162001e26565b905062001f0960c083018562001e7c565b62001f1860e08301846200136e565b979650505050505050565b5f819050919050565b5f65ffffffffffff82169050919050565b5f62001f5d62001f5762001f518462001f23565b620016e4565b62001f2c565b9050919050565b62001f6f8162001f3d565b82525050565b7f63555344430000000000000000000000000000000000000000000000000000005f82015250565b5f62001fab600583620013a4565b915062001fb88262001f75565b602082019050919050565b5f6101008201905062001fd95f8301896200136e565b62001fe860208301886200136e565b62001ff760408301876200136e565b62002006606083018662001f64565b8181036080830152620020198162001f9d565b905081810360a08301526200202e8162001f9d565b90506200203f60c083018562001e7c565b6200204e60e08301846200136e565b979650505050505050565b6200206481620016db565b81146200206f575f80fd5b50565b5f81519050620020828162002059565b92915050565b5f60208284031215620020a0576200209f62001459565b5b5f620020af8482850162002072565b91505092915050565b5f819050919050565b5f620020e1620020db620020d584620020b8565b620016e4565b620016db565b9050919050565b620020f381620020c1565b82525050565b5f6040820190506200210e5f8301856200136e565b6200211d6020830184620020e8565b9392505050565b5f819050919050565b5f6200214d62002147620021418462002124565b620016e4565b620016db565b9050919050565b6200215f816200212d565b82525050565b5f6040820190506200217a5f8301856200136e565b62002189602083018462002154565b9392505050565b5f620021b0620021aa620021a48462001be1565b620016e4565b620016db565b9050919050565b620021c28162002190565b82525050565b5f604082019050620021dd5f8301856200136e565b620021ec6020830184620021b7565b9392505050565b5f819050919050565b5f6200221c620022166200221084620021f3565b620016e4565b620016db565b9050919050565b6200222e81620021fc565b82525050565b5f604082019050620022495f8301856200136e565b62002258602083018462002223565b9392505050565b5f81905092915050565b5f8154620022778162001625565b6200228381866200225f565b9450600182165f8114620022a05760018114620022b657620022ec565b60ff1983168652811515820286019350620022ec565b620022c18562001659565b5f5b83811015620022e457815481890152600182019150602081019050620022c3565b838801955050505b50505092915050565b5f62002302828462002269565b915081905092915050565b5f6040820190508181035f830152620023278185620013ee565b90506200233860208301846200136e565b939250505056fe60806040523480156200001157600080fd5b5060405162005dfb38038062005dfb83398181016040526101008110156200003857600080fd5b81516020830151604080850151606086015160808701805193519597949692959194919392820192846401000000008211156200007457600080fd5b9083019060208201858111156200008a57600080fd5b8251640100000000811182820188101715620000a557600080fd5b82525081516020918201929091019080838360005b83811015620000d4578181015183820152602001620000ba565b50505050905090810190601f168015620001025780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200012657600080fd5b9083019060208201858111156200013c57600080fd5b82516401000000008111828201881017156200015757600080fd5b82525081516020918201929091019080838360005b83811015620001865781810151838201526020016200016c565b50505050905090810190601f168015620001b45780820380516001836020036101000a031916815260200191505b506040908152602082015191015160038054610100600160a81b03191633610100021790559092509050620001ef8888888888888862000223565b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055506200090d95505050505050565b6200023e868686868686620002d260201b6200155c1760201c565b601180546001600160a01b0319166001600160a01b038981169190911791829055604080516318160ddd60e01b8152905192909116916318160ddd91600480820192602092909190829003018186803b1580156200029b57600080fd5b505afa158015620002b0573d6000803e3d6000fd5b505050506040513d6020811015620002c757600080fd5b505050505050505050565b60035461010090046001600160a01b03163314620003225760405162461bcd60e51b815260040180806020018281038252602481526020018062005d626024913960400191505060405180910390fd5b600954158015620003335750600a54155b620003705760405162461bcd60e51b815260040180806020018281038252602381526020018062005d866023913960400191505060405180910390fd5b600784905583620003b35760405162461bcd60e51b815260040180806020018281038252603081526020018062005da96030913960400191505060405180910390fd5b6000620003c9876001600160e01b03620004e816565b905080156200041f576040805162461bcd60e51b815260206004820152601a60248201527f73657474696e6720636f6d7074726f6c6c6572206661696c6564000000000000604482015290519081900360640190fd5b620004326001600160e01b036200065016565b600955670de0b6b3a7640000600a5562000455866001600160e01b036200065516565b90508015620004965760405162461bcd60e51b815260040180806020018281038252602281526020018062005dd96022913960400191505060405180910390fd5b8351620004ab9060019060208701906200086b565b508251620004c19060029060208601906200086b565b50506003805460ff90921660ff199283161790556000805490911660011790555050505050565b60035460009061010090046001600160a01b0316331462000522576200051a6001603f6001600160e01b03620007fb16565b90506200064b565b60055460408051623f1ee960e11b815290516001600160a01b0392831692851691627e3dd2916004808301926020929190829003018186803b1580156200056857600080fd5b505afa1580156200057d573d6000803e3d6000fd5b505050506040513d60208110156200059457600080fd5b5051620005e8576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190a160005b9150505b919050565b435b90565b600354600090819061010090046001600160a01b03163314620006925762000689600160426001600160e01b03620007fb16565b9150506200064b565b620006a56001600160e01b036200065016565b60095414620006c55762000689600a60416001600160e01b03620007fb16565b600660009054906101000a90046001600160a01b03169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200071757600080fd5b505afa1580156200072c573d6000803e3d6000fd5b505050506040513d60208110156200074357600080fd5b505162000797576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a1600062000647565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360108111156200082b57fe5b8360508111156200083857fe5b604080519283526020830191909152600082820152519081900360600190a18260108111156200086457fe5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620008ae57805160ff1916838001178555620008de565b82800160010185558215620008de579182015b82811115620008de578251825591602001919060010190620008c1565b50620008ec929150620008f0565b5090565b6200065291905b80821115620008ec5760008155600101620008f7565b615445806200091d6000396000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c80637f1e06be116101bd578063bd6d894d116100f9578063f2b3abbd116100a2578063f851a4401161007c578063f851a44014610b2a578063f8f9da2814610b32578063fca7820b14610b3a578063fe9c44ae14610b5757610341565b8063f2b3abbd14610ac6578063f3fdb15a14610aec578063f5e3c46214610af457610341565b8063db006a75116100d3578063db006a7514610a73578063dd62ed3e14610a90578063e9c714f214610abe57610341565b8063bd6d894d14610a02578063c37f68e214610a0a578063c5ebeaec14610a5657610341565b8063a0712d6811610166578063aa5af0fd11610140578063aa5af0fd14610996578063ae9d70b01461099e578063b2a02ff1146109a6578063b71d1a0c146109dc57610341565b8063a0712d6814610945578063a6afed9514610962578063a9059cbb1461096a57610341565b806395d89b411161019757806395d89b41146107c557806395dd9193146107cd57806399d8c1b4146107f357610341565b80637f1e06be1461077a578063852a12e3146107a05780638f840ddd146107bd57610341565b8063313ce5671161028c5780635fe3b567116102355780636c540baf1161020f5780636c540baf1461073c5780636f307dc31461074457806370a082311461074c57806373acee981461077257610341565b80635fe3b5671461070f578063601a0bf1146107175780636752e7021461073457610341565b80633e941010116102665780633e941010146106c45780634576b5db146106e157806347bd37181461070757610341565b8063313ce567146106785780633af9e669146106965780633b1d21a2146106bc57610341565b8063182df0f5116102ee57806323b872dd116102c857806323b872dd146105f25780632608f81814610628578063267822471461065457610341565b8063182df0f5146104685780631a31d465146104705780631be19560146105cc57610341565b8063173b99041161031f578063173b99041461043257806317bfdfbc1461043a57806318160ddd1461046057610341565b806306fdde0314610346578063095ea7b3146103c35780630e75270214610403575b600080fd5b61034e610b5f565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610388578181015183820152602001610370565b50505050905090810190601f1680156103b55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ef600480360360408110156103d957600080fd5b506001600160a01b038135169060200135610bec565b604080519115158252519081900360200190f35b6104206004803603602081101561041957600080fd5b5035610c59565b60408051918252519081900360200190f35b610420610c6f565b6104206004803603602081101561045057600080fd5b50356001600160a01b0316610c75565b610420610d35565b610420610d3b565b6105ca600480360360e081101561048657600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156104c957600080fd5b8201836020820111156104db57600080fd5b803590602001918460018302840111640100000000831117156104fd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561055057600080fd5b82018360208201111561056257600080fd5b8035906020019184600183028401116401000000008311171561058457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff169150610d9e9050565b005b6105ca600480360360208110156105e257600080fd5b50356001600160a01b0316610e3d565b6103ef6004803603606081101561060857600080fd5b506001600160a01b03813581169160208101359091169060400135610f79565b6104206004803603604081101561063e57600080fd5b506001600160a01b038135169060200135610feb565b61065c611001565b604080516001600160a01b039092168252519081900360200190f35b610680611010565b6040805160ff9092168252519081900360200190f35b610420600480360360208110156106ac57600080fd5b50356001600160a01b0316611019565b6104206110cf565b610420600480360360208110156106da57600080fd5b50356110de565b610420600480360360208110156106f757600080fd5b50356001600160a01b03166110e9565b61042061123e565b61065c611244565b6104206004803603602081101561072d57600080fd5b5035611253565b6104206112ee565b6104206112f9565b61065c6112ff565b6104206004803603602081101561076257600080fd5b50356001600160a01b031661130e565b610420611329565b6105ca6004803603602081101561079057600080fd5b50356001600160a01b03166113df565b610420600480360360208110156107b657600080fd5b5035611496565b6104206114a1565b61034e6114a7565b610420600480360360208110156107e357600080fd5b50356001600160a01b03166114ff565b6105ca600480360360c081101561080957600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561084457600080fd5b82018360208201111561085657600080fd5b8035906020019184600183028401116401000000008311171561087857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156108cb57600080fd5b8201836020820111156108dd57600080fd5b803590602001918460018302840111640100000000831117156108ff57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff16915061155c9050565b6104206004803603602081101561095b57600080fd5b5035611743565b61042061174f565b6103ef6004803603604081101561098057600080fd5b506001600160a01b038135169060200135611aa7565b610420611b18565b610420611b1e565b610420600480360360608110156109bc57600080fd5b506001600160a01b03813581169160208101359091169060400135611bbd565b610420600480360360208110156109f257600080fd5b50356001600160a01b0316611c2e565b610420611cba565b610a3060048036036020811015610a2057600080fd5b50356001600160a01b0316611d76565b604080519485526020850193909352838301919091526060830152519081900360800190f35b61042060048036036020811015610a6c57600080fd5b5035611e0b565b61042060048036036020811015610a8957600080fd5b5035611e16565b61042060048036036040811015610aa657600080fd5b506001600160a01b0381358116916020013516611e21565b610420611e4c565b61042060048036036020811015610adc57600080fd5b50356001600160a01b0316611f5c565b61065c611f96565b61042060048036036060811015610b0a57600080fd5b506001600160a01b03813581169160208101359160409091013516611fa5565b61065c611fbd565b610420611fd1565b61042060048036036020811015610b5057600080fd5b5035612035565b6103ef6120b3565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be45780601f10610bb957610100808354040283529160200191610be4565b820191906000526020600020905b815481529060010190602001808311610bc757829003601f168201915b505050505081565b336000818152600f602090815260408083206001600160a01b03871680855290835281842086905581518681529151939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a360019150505b92915050565b600080610c65836120b8565b509150505b919050565b60085481565b6000805460ff16610cba576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155610ccc61174f565b14610d17576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b610d20826114ff565b90505b6000805460ff19166001179055919050565b600d5481565b6000806000610d48612161565b90925090506000826003811115610d5b57fe5b14610d975760405162461bcd60e51b815260040180806020018281038252603581526020018061535c6035913960400191505060405180910390fd5b9150505b90565b610dac86868686868661155c565b601180546001600160a01b0319166001600160a01b038981169190911791829055604080516318160ddd60e01b8152905192909116916318160ddd91600480820192602092909190829003018186803b158015610e0857600080fd5b505afa158015610e1c573d6000803e3d6000fd5b505050506040513d6020811015610e3257600080fd5b505050505050505050565b6011546001600160a01b0382811691161415610e8a5760405162461bcd60e51b815260040180806020018281038252603281526020018061518b6032913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b158015610ed457600080fd5b505afa158015610ee8573d6000803e3d6000fd5b505050506040513d6020811015610efe57600080fd5b50516003546040805163a9059cbb60e01b81526101009092046001600160a01b03908116600484015260248301849052905192935084169163a9059cbb9160448082019260009290919082900301818387803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b505050505050565b6000805460ff16610fbe576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155610fd433868686612210565b1490506000805460ff191660011790559392505050565b600080610ff8848461249c565b50949350505050565b6004546001600160a01b031681565b60035460ff1681565b6000611023614f9e565b6040518060200160405280611036611cba565b90526001600160a01b0384166000908152600e6020526040812054919250908190611062908490612547565b9092509050600082600381111561107557fe5b146110c7576040805162461bcd60e51b815260206004820152601f60248201527f62616c616e636520636f756c64206e6f742062652063616c63756c6174656400604482015290519081900360640190fd5b949350505050565b60006110d961259b565b905090565b6000610c538261261b565b60035460009061010090046001600160a01b031633146111165761110f6001603f6126af565b9050610c6a565b60055460408051623f1ee960e11b815290516001600160a01b0392831692851691627e3dd2916004808301926020929190829003018186803b15801561115b57600080fd5b505afa15801561116f573d6000803e3d6000fd5b505050506040513d602081101561118557600080fd5b50516111d8576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190a160005b9392505050565b600b5481565b6005546001600160a01b031681565b6000805460ff16611298576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff191681556112aa61174f565b905080156112d0576112c88160108111156112c157fe5b60306126af565b915050610d23565b6112d983612715565b9150506000805460ff19166001179055919050565b666379da05b6000081565b60095481565b6011546001600160a01b031681565b6001600160a01b03166000908152600e602052604090205490565b6000805460ff1661136e576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561138061174f565b146113cb576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b50600b546000805460ff1916600117905590565b60035461010090046001600160a01b0316331461142d5760405162461bcd60e51b815260040180806020018281038252602d8152602001806151ed602d913960400191505060405180910390fd5b601154604080516317066a5760e21b81526001600160a01b03848116600483015291519190921691635c19a95c91602480830192600092919082900301818387803b15801561147b57600080fd5b505af115801561148f573d6000803e3d6000fd5b5050505050565b6000610c5382612848565b600c5481565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610be45780601f10610bb957610100808354040283529160200191610be4565b600080600061150d846128c9565b9092509050600082600381111561152057fe5b146112375760405162461bcd60e51b81526004018080602001828103825260378152602001806152676037913960400191505060405180910390fd5b60035461010090046001600160a01b031633146115aa5760405162461bcd60e51b81526004018080602001828103825260248152602001806151446024913960400191505060405180910390fd5b6009541580156115ba5750600a54155b6115f55760405162461bcd60e51b81526004018080602001828103825260238152602001806151686023913960400191505060405180910390fd5b6007849055836116365760405162461bcd60e51b81526004018080602001828103825260308152602001806151bd6030913960400191505060405180910390fd5b6000611641876110e9565b90508015611696576040805162461bcd60e51b815260206004820152601a60248201527f73657474696e6720636f6d7074726f6c6c6572206661696c6564000000000000604482015290519081900360640190fd5b61169e61297d565b600955670de0b6b3a7640000600a556116b686612981565b905080156116f55760405162461bcd60e51b815260040180806020018281038252602281526020018061521a6022913960400191505060405180910390fd5b8351611708906001906020870190614fb1565b50825161171c906002906020860190614fb1565b50506003805460ff90921660ff199283161790556000805490911660011790555050505050565b600080610c6583612af6565b60008061175a61297d565b6009549091508082141561177357600092505050610d9b565b600061177d61259b565b600b54600c54600a54600654604080516315f2405360e01b815260048101879052602481018690526044810185905290519596509394929391926000926001600160a01b03909216916315f24053916064808301926020929190829003018186803b1580156117eb57600080fd5b505afa1580156117ff573d6000803e3d6000fd5b505050506040513d602081101561181557600080fd5b5051905065048c27395000811115611874576040805162461bcd60e51b815260206004820152601c60248201527f626f72726f772072617465206973206162737572646c79206869676800000000604482015290519081900360640190fd5b6000806118818989612b77565b9092509050600082600381111561189457fe5b146118e6576040805162461bcd60e51b815260206004820152601f60248201527f636f756c64206e6f742063616c63756c61746520626c6f636b2064656c746100604482015290519081900360640190fd5b6118ee614f9e565b60008060008061190c60405180602001604052808a81525087612b9a565b9097509450600087600381111561191f57fe5b146119515761193c6009600689600381111561193757fe5b612c02565b9e505050505050505050505050505050610d9b565b61195b858c612547565b9097509350600087600381111561196e57fe5b146119865761193c6009600189600381111561193757fe5b611990848c612c68565b909750925060008760038111156119a357fe5b146119bb5761193c6009600489600381111561193757fe5b6119d66040518060200160405280600854815250858c612c8e565b909750915060008760038111156119e957fe5b14611a015761193c6009600589600381111561193757fe5b611a0c858a8b612c8e565b90975090506000876003811115611a1f57fe5b14611a375761193c6009600389600381111561193757fe5b60098e9055600a819055600b839055600c829055604080518d8152602081018690528082018390526060810185905290517f4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc049181900360800190a160009e50505050505050505050505050505090565b6000805460ff16611aec576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155611b0233338686612210565b1490506000805460ff1916600117905592915050565b600a5481565b6006546000906001600160a01b031663b8168816611b3a61259b565b600b54600c546008546040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060206040518083038186803b158015611b8c57600080fd5b505afa158015611ba0573d6000803e3d6000fd5b505050506040513d6020811015611bb657600080fd5b5051905090565b6000805460ff16611c02576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19169055611c1833858585612cea565b90506000805460ff191660011790559392505050565b60035460009061010090046001600160a01b03163314611c545761110f600160456126af565b600480546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000611237565b6000805460ff16611cff576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155611d1161174f565b14611d5c576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b611d64610d3b565b90506000805460ff1916600117905590565b6001600160a01b0381166000908152600e6020526040812054819081908190818080611da1896128c9565b935090506000816003811115611db357fe5b14611dd15760095b975060009650869550859450611e049350505050565b611dd9612161565b925090506000816003811115611deb57fe5b14611df7576009611dbb565b5060009650919450925090505b9193509193565b6000610c53826130c4565b6000610c5382613143565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b6004546000906001600160a01b031633141580611e67575033155b15611e7f57611e78600160006126af565b9050610d9b565b60038054600480546001600160a01b0381811661010081810274ffffffffffffffffffffffffffffffffffffffff0019871617968790556001600160a01b031990931690935560408051948390048216808652929095041660208401528351909391927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a1600454604080516001600160a01b038085168252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a160009250505090565b600080611f6761174f565b90508015611f8d57611f85816010811115611f7e57fe5b60406126af565b915050610c6a565b61123783612981565b6006546001600160a01b031681565b600080611fb38585856131bd565b5095945050505050565b60035461010090046001600160a01b031681565b6006546000906001600160a01b03166315f24053611fed61259b565b600b54600c546040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015611b8c57600080fd5b6000805460ff1661207a576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561208c61174f565b905080156120aa576112c88160108111156120a357fe5b60466126af565b6112d9836132ef565b600181565b60008054819060ff166120ff576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561211161174f565b9050801561213c5761212f81601081111561212857fe5b60366126af565b92506000915061214d9050565b612147333386613397565b92509250505b6000805460ff191660011790559092909150565b600d5460009081908061217c5750506007546000915061220c565b600061218661259b565b90506000612192614f9e565b60006121a384600b54600c546136e5565b9350905060008160038111156121b557fe5b146121ca5795506000945061220c9350505050565b6121d48386613723565b9250905060008160038111156121e657fe5b146121fb5795506000945061220c9350505050565b505160009550935061220c92505050565b9091565b600554604080516317b9b84b60e31b81523060048201526001600160a01b03868116602483015285811660448301526064820185905291516000938493169163bdcdc25891608480830192602092919082900301818787803b15801561227557600080fd5b505af1158015612289573d6000803e3d6000fd5b505050506040513d602081101561229f57600080fd5b5051905080156122be576122b66003604a83612c02565b9150506110c7565b836001600160a01b0316856001600160a01b031614156122e4576122b66002604b6126af565b60006001600160a01b038781169087161415612303575060001961232b565b506001600160a01b038086166000908152600f60209081526040808320938a16835292905220545b60008060008061233b8589612b77565b9094509250600084600381111561234e57fe5b1461236c5761235f6009604b6126af565b96505050505050506110c7565b6001600160a01b038a166000908152600e602052604090205461238f9089612b77565b909450915060008460038111156123a257fe5b146123b35761235f6009604c6126af565b6001600160a01b0389166000908152600e60205260409020546123d69089612c68565b909450905060008460038111156123e957fe5b146123fa5761235f6009604d6126af565b6001600160a01b03808b166000908152600e6020526040808220859055918b168152208190556000198514612452576001600160a01b03808b166000908152600f60209081526040808320938f168352929052208390555b886001600160a01b03168a6001600160a01b03166000805160206152d88339815191528a6040518082815260200191505060405180910390a35060009a9950505050505050505050565b60008054819060ff166124e3576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff191681556124f561174f565b905080156125205761251381601081111561250c57fe5b60356126af565b9250600091506125319050565b61252b338686613397565b92509250505b6000805460ff1916600117905590939092509050565b6000806000612554614f9e565b61255e8686612b9a565b9092509050600082600381111561257157fe5b146125825750915060009050612594565b600061258d826137d3565b9350935050505b9250929050565b601154604080516370a0823160e01b815230600482015290516000926001600160a01b03169182916370a0823191602480820192602092909190829003018186803b1580156125e957600080fd5b505afa1580156125fd573d6000803e3d6000fd5b505050506040513d602081101561261357600080fd5b505191505090565b6000805460ff16612660576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561267261174f565b90508015612690576112c881601081111561268957fe5b604e6126af565b612699836137e2565b509150506000805460ff19166001179055919050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360108111156126de57fe5b8360508111156126ea57fe5b604080519283526020830191909152600082820152519081900360600190a182601081111561123757fe5b600354600090819061010090046001600160a01b0316331461273d57611f85600160316126af565b61274561297d565b6009541461275957611f85600a60336126af565b8261276261259b565b101561277457611f85600e60326126af565b600c5483111561278a57611f85600260346126af565b50600c54828103908111156127d05760405162461bcd60e51b81526004018080602001828103825260248152602001806153ed6024913960400191505060405180910390fd5b600c8190556003546127f09061010090046001600160a01b0316846138ca565b600354604080516101009092046001600160a01b0316825260208201859052818101839052517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e916060908290030190a16000611237565b6000805460ff1661288d576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561289f61174f565b905080156128bd576112c88160108111156128b657fe5b60276126af565b6112d9336000856139c1565b6001600160a01b03811660009081526010602052604081208054829182918291829161290057506000945084935061297892505050565b6129108160000154600a54613e88565b9094509250600084600381111561292357fe5b14612938575091935060009250612978915050565b612946838260010154613ec7565b9094509150600084600381111561295957fe5b1461296e575091935060009250612978915050565b5060009450925050505b915091565b4390565b600354600090819061010090046001600160a01b031633146129a957611f85600160426126af565b6129b161297d565b600954146129c557611f85600a60416126af565b600660009054906101000a90046001600160a01b03169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1657600080fd5b505afa158015612a2a573d6000803e3d6000fd5b505050506040513d6020811015612a4057600080fd5b5051612a93576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000611237565b60008054819060ff16612b3d576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155612b4f61174f565b90508015612b6d5761212f816010811115612b6657fe5b601e6126af565b6121473385613ef2565b600080838311612b8e575060009050818303612594565b50600390506000612594565b6000612ba4614f9e565b600080612bb5866000015186613e88565b90925090506000826003811115612bc857fe5b14612be757506040805160208101909152600081529092509050612594565b60408051602081019091529081526000969095509350505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846010811115612c3157fe5b846050811115612c3d57fe5b604080519283526020830191909152818101859052519081900360600190a18360108111156110c757fe5b600080838301848110612c8057600092509050612594565b506002915060009050612594565b6000806000612c9b614f9e565b612ca58787612b9a565b90925090506000826003811115612cb857fe5b14612cc95750915060009050612ce2565b612cdb612cd5826137d3565b86612c68565b9350935050505b935093915050565b6005546040805163d02f735160e01b81523060048201526001600160a01b038781166024830152868116604483015285811660648301526084820185905291516000938493169163d02f73519160a480830192602092919082900301818787803b158015612d5757600080fd5b505af1158015612d6b573d6000803e3d6000fd5b505050506040513d6020811015612d8157600080fd5b505190508015612d98576122b66003601b83612c02565b846001600160a01b0316846001600160a01b03161415612dbe576122b66006601c6126af565b612dc661502f565b6001600160a01b0385166000908152600e6020526040902054612de99085612b77565b6020830181905282826003811115612dfd57fe5b6003811115612e0857fe5b9052506000905081516003811115612e1c57fe5b14612e4157612e386009601a8360000151600381111561193757fe5b925050506110c7565b612e60846040518060200160405280666379da05b600008152506142c2565b60808201819052612e729085906142ea565b6060820152612e7f612161565b60c0830181905282826003811115612e9357fe5b6003811115612e9e57fe5b9052506000905081516003811115612eb257fe5b14612f04576040805162461bcd60e51b815260206004820152601860248201527f65786368616e67652072617465206d617468206572726f720000000000000000604482015290519081900360640190fd5b612f2460405180602001604052808360c00151815250826080015161432c565b60a08201819052600c54612f379161434b565b60e0820152600d546080820151612f4e91906142ea565b6101008201526001600160a01b0386166000908152600e60205260409020546060820151612f7c9190612c68565b6040830181905282826003811115612f9057fe5b6003811115612f9b57fe5b9052506000905081516003811115612faf57fe5b14612fcb57612e38600960198360000151600381111561193757fe5b60e0810151600c55610100810151600d556020808201516001600160a01b038088166000818152600e855260408082209490945583860151928b168082529084902092909255606085015183519081529251919390926000805160206152d8833981519152929081900390910190a36080810151604080519182525130916001600160a01b038816916000805160206152d88339815191529181900360200190a360a081015160e082015160408051308152602081019390935282810191909152517fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc59181900360600190a16000979650505050505050565b6000805460ff16613109576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561311b61174f565b90508015613139576112c881601081111561313257fe5b60086126af565b6112d93384614381565b6000805460ff16613188576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561319a61174f565b905080156131b1576112c88160108111156128b657fe5b6112d9338460006139c1565b60008054819060ff16613204576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561321661174f565b905080156132415761323481601081111561322d57fe5b600f6126af565b9250600091506132d89050565b836001600160a01b031663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561327c57600080fd5b505af1158015613290573d6000803e3d6000fd5b505050506040513d60208110156132a657600080fd5b5051905080156132c6576132348160108111156132bf57fe5b60106126af565b6132d233878787614615565b92509250505b6000805460ff191660011790559094909350915050565b60035460009061010090046001600160a01b031633146133155761110f600160476126af565b61331d61297d565b600954146133315761110f600a60486126af565b670de0b6b3a764000082111561334d5761110f600260496126af565b6008805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000611237565b60055460408051631200453160e11b81523060048201526001600160a01b0386811660248301528581166044830152606482018590529151600093849384939116916324008a629160848082019260209290919082900301818787803b15801561340057600080fd5b505af1158015613414573d6000803e3d6000fd5b505050506040513d602081101561342a57600080fd5b50519050801561344e576134416003603883612c02565b925060009150612ce29050565b61345661297d565b6009541461346a57613441600a60396126af565b61347261507c565b6001600160a01b038616600090815260106020526040902060010154606082015261349c866128c9565b60808301819052602083018260038111156134b357fe5b60038111156134be57fe5b90525060009050816020015160038111156134d557fe5b146134ff576134f1600960378360200151600381111561193757fe5b935060009250612ce2915050565b6000198514156135185760808101516040820152613520565b604081018590525b61352e878260400151614b10565b60e08201819052608082015161354391612b77565b60a083018190526020830182600381111561355a57fe5b600381111561356557fe5b905250600090508160200151600381111561357c57fe5b146135b85760405162461bcd60e51b815260040180806020018281038252603a81526020018061529e603a913960400191505060405180910390fd5b6135c8600b548260e00151612b77565b60c08301819052602083018260038111156135df57fe5b60038111156135ea57fe5b905250600090508160200151600381111561360157fe5b1461363d5760405162461bcd60e51b81526004018080602001828103825260318152602001806152f86031913960400191505060405180910390fd5b60a080820180516001600160a01b03808a16600081815260106020908152604091829020948555600a5460019095019490945560c0870151600b81905560e088015195518251948f16855294840192909252828101949094526060820192909252608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1929181900390910190a160e00151600097909650945050505050565b6000806000806136f58787612c68565b9092509050600082600381111561370857fe5b146137195750915060009050612ce2565b612cdb8186612b77565b600061372d614f9e565b60008061374286670de0b6b3a7640000613e88565b9092509050600082600381111561375557fe5b1461377457506040805160208101909152600081529092509050612594565b6000806137818388613ec7565b9092509050600082600381111561379457fe5b146137b657506040805160208101909152600081529094509250612594915050565b604080516020810190915290815260009890975095505050505050565b51670de0b6b3a7640000900490565b6000806000806137f061297d565b6009541461380f57613804600a604f6126af565b935091506129789050565b6138193386614b10565b905080600c54019150600c54821015613879576040805162461bcd60e51b815260206004820181905260248201527f61646420726573657276657320756e6578706563746564206f766572666c6f77604482015290519081900360640190fd5b600c829055604080513381526020810183905280820184905290517fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc59181900360600190a160009350915050915091565b6011546040805163a9059cbb60e01b81526001600160a01b0385811660048301526024820185905291519190921691829163a9059cbb9160448082019260009290919082900301818387803b15801561392257600080fd5b505af1158015613936573d6000803e3d6000fd5b5050505060003d60008114613952576020811461395c57600080fd5b6000199150613968565b60206000803e60005191505b50806139bb576040805162461bcd60e51b815260206004820152601960248201527f544f4b454e5f5452414e534645525f4f55545f4641494c454400000000000000604482015290519081900360640190fd5b50505050565b60008215806139ce575081155b613a095760405162461bcd60e51b81526004018080602001828103825260348152602001806153b96034913960400191505060405180910390fd5b613a116150c2565b613a19612161565b6040830181905260208301826003811115613a3057fe5b6003811115613a3b57fe5b9052506000905081602001516003811115613a5257fe5b14613a7657613a6e6009602b8360200151600381111561193757fe5b915050611237565b8315613af7576060810184905260408051602081018252908201518152613a9d9085612547565b6080830181905260208301826003811115613ab457fe5b6003811115613abf57fe5b9052506000905081602001516003811115613ad657fe5b14613af257613a6e600960298360200151600381111561193757fe5b613b70565b613b138360405180602001604052808460400151815250614d5a565b6060830181905260208301826003811115613b2a57fe5b6003811115613b3557fe5b9052506000905081602001516003811115613b4c57fe5b14613b6857613a6e6009602a8360200151600381111561193757fe5b608081018390525b60055460608201516040805163eabe7d9160e01b81523060048201526001600160a01b03898116602483015260448201939093529051600093929092169163eabe7d919160648082019260209290919082900301818787803b158015613bd557600080fd5b505af1158015613be9573d6000803e3d6000fd5b505050506040513d6020811015613bff57600080fd5b505190508015613c1f57613c166003602883612c02565b92505050611237565b613c2761297d565b60095414613c3b57613c16600a602c6126af565b613c4b600d548360600151612b77565b60a0840181905260208401826003811115613c6257fe5b6003811115613c6d57fe5b9052506000905082602001516003811115613c8457fe5b14613ca057613c166009602e8460200151600381111561193757fe5b6001600160a01b0386166000908152600e60205260409020546060830151613cc89190612b77565b60c0840181905260208401826003811115613cdf57fe5b6003811115613cea57fe5b9052506000905082602001516003811115613d0157fe5b14613d1d57613c166009602d8460200151600381111561193757fe5b8160800151613d2a61259b565b1015613d3c57613c16600e602f6126af565b613d4a8683608001516138ca565b60a0820151600d5560c08201516001600160a01b0387166000818152600e60209081526040918290209390935560608501518151908152905130936000805160206152d8833981519152928290030190a36080820151606080840151604080516001600160a01b038b168152602081019490945283810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9299281900390910190a160055460808301516060840151604080516351dff98960e01b81523060048201526001600160a01b038b81166024830152604482019490945260648101929092525191909216916351dff98991608480830192600092919082900301818387803b158015613e5d57600080fd5b505af1158015613e71573d6000803e3d6000fd5b5060009250613e7e915050565b9695505050505050565b60008083613e9b57506000905080612594565b83830283858281613ea857fe5b0414613ebc57506002915060009050612594565b600092509050612594565b60008082613edb5750600190506000612594565b6000838581613ee657fe5b04915091509250929050565b60055460408051634ef4c3e160e01b81523060048201526001600160a01b03858116602483015260448201859052915160009384938493911691634ef4c3e19160648082019260209290919082900301818787803b158015613f5357600080fd5b505af1158015613f67573d6000803e3d6000fd5b505050506040513d6020811015613f7d57600080fd5b505190508015613fa157613f946003601f83612c02565b9250600091506125949050565b613fa961297d565b60095414613fbd57613f94600a60226126af565b613fc56150c2565b613fcd612161565b6040830181905260208301826003811115613fe457fe5b6003811115613fef57fe5b905250600090508160200151600381111561400657fe5b1461403057614022600960218360200151600381111561193757fe5b935060009250612594915050565b61403a8686614b10565b60c082018190526040805160208101825290830151815261405b9190614d5a565b606083018190526020830182600381111561407257fe5b600381111561407d57fe5b905250600090508160200151600381111561409457fe5b146140e6576040805162461bcd60e51b815260206004820181905260248201527f4d494e545f45584348414e47455f43414c43554c4154494f4e5f4641494c4544604482015290519081900360640190fd5b6140f6600d548260600151612c68565b608083018190526020830182600381111561410d57fe5b600381111561411857fe5b905250600090508160200151600381111561412f57fe5b1461416b5760405162461bcd60e51b81526004018080602001828103825260288152602001806153916028913960400191505060405180910390fd5b6001600160a01b0386166000908152600e602052604090205460608201516141939190612c68565b60a08301819052602083018260038111156141aa57fe5b60038111156141b557fe5b90525060009050816020015160038111156141cc57fe5b146142085760405162461bcd60e51b815260040180806020018281038252602b81526020018061523c602b913960400191505060405180910390fd5b6080810151600d5560a08101516001600160a01b0387166000818152600e60209081526040918290209390935560c084015160608086015183519485529484019190915282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160a01b0388169130916000805160206152d88339815191529181900360200190a360c001516000969095509350505050565b6000670de0b6b3a76400006142db848460000151614d71565b816142e257fe5b049392505050565b600061123783836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f770000000000000000000000815250614db3565b6000614336614f9e565b6143408484614e4a565b90506110c7816137d3565b60006112378383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b815250614e74565b6005546040805163368f515360e21b81523060048201526001600160a01b0385811660248301526044820185905291516000938493169163da3d454c91606480830192602092919082900301818787803b1580156143de57600080fd5b505af11580156143f2573d6000803e3d6000fd5b505050506040513d602081101561440857600080fd5b5051905080156144275761441f6003600e83612c02565b915050610c53565b61442f61297d565b600954146144425761441f600a806126af565b8261444b61259b565b101561445d5761441f600e60096126af565b614465615100565b61446e856128c9565b602083018190528282600381111561448257fe5b600381111561448d57fe5b90525060009050815160038111156144a157fe5b146144c6576144bd600960078360000151600381111561193757fe5b92505050610c53565b6144d4816020015185612c68565b60408301819052828260038111156144e857fe5b60038111156144f357fe5b905250600090508151600381111561450757fe5b14614523576144bd6009600c8360000151600381111561193757fe5b61452f600b5485612c68565b606083018190528282600381111561454357fe5b600381111561454e57fe5b905250600090508151600381111561456257fe5b1461457e576144bd6009600b8360000151600381111561193757fe5b61458885856138ca565b604080820180516001600160a01b03881660008181526010602090815290859020928355600a54600190930192909255606080860151600b81905593518551928352928201899052818501929092529081019190915290517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab809181900360800190a1600095945050505050565b60055460408051632fe3f38f60e11b81523060048201526001600160a01b0384811660248301528781166044830152868116606483015260848201869052915160009384938493911691635fc7e71e9160a48082019260209290919082900301818787803b15801561468657600080fd5b505af115801561469a573d6000803e3d6000fd5b505050506040513d60208110156146b057600080fd5b5051905080156146d4576146c76003601283612c02565b925060009150614b079050565b6146dc61297d565b600954146146f0576146c7600a60166126af565b6146f861297d565b846001600160a01b0316636c540baf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561473157600080fd5b505afa158015614745573d6000803e3d6000fd5b505050506040513d602081101561475b57600080fd5b50511461476e576146c7600a60116126af565b866001600160a01b0316866001600160a01b03161415614794576146c7600660176126af565b846147a5576146c7600760156126af565b6000198514156147bb576146c7600760146126af565b6000806147c9898989613397565b909250905081156147f9576147ea8260108111156147e357fe5b60186126af565b945060009350614b0792505050565b6005546040805163c488847b60e01b81523060048201526001600160a01b038981166024830152604482018590528251600094859492169263c488847b926064808301939192829003018186803b15801561485357600080fd5b505afa158015614867573d6000803e3d6000fd5b505050506040513d604081101561487d57600080fd5b508051602090910151909250905081156148c85760405162461bcd60e51b81526004018080602001828103825260338152602001806153296033913960400191505060405180910390fd5b80886001600160a01b03166370a082318c6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561491f57600080fd5b505afa158015614933573d6000803e3d6000fd5b505050506040513d602081101561494957600080fd5b5051101561499e576040805162461bcd60e51b815260206004820152601860248201527f4c49515549444154455f5345495a455f544f4f5f4d5543480000000000000000604482015290519081900360640190fd5b60006001600160a01b0389163014156149c4576149bd308d8d85612cea565b9050614a4e565b6040805163b2a02ff160e01b81526001600160a01b038e811660048301528d81166024830152604482018590529151918b169163b2a02ff1916064808201926020929091908290030181600087803b158015614a1f57600080fd5b505af1158015614a33573d6000803e3d6000fd5b505050506040513d6020811015614a4957600080fd5b505190505b8015614aa1576040805162461bcd60e51b815260206004820152601460248201527f746f6b656e207365697a757265206661696c6564000000000000000000000000604482015290519081900360640190fd5b604080516001600160a01b03808f168252808e1660208301528183018790528b1660608201526080810184905290517f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb529181900360a00190a16000975092955050505050505b94509492505050565b601154604080516370a0823160e01b815230600482015290516000926001600160a01b031691839183916370a08231916024808301926020929190829003018186803b158015614b5f57600080fd5b505afa158015614b73573d6000803e3d6000fd5b505050506040513d6020811015614b8957600080fd5b5051604080516323b872dd60e01b81526001600160a01b038881166004830152306024830152604482018890529151929350908416916323b872dd9160648082019260009290919082900301818387803b158015614be657600080fd5b505af1158015614bfa573d6000803e3d6000fd5b5050505060003d60008114614c165760208114614c2057600080fd5b6000199150614c2c565b60206000803e60005191505b5080614c7f576040805162461bcd60e51b815260206004820152601860248201527f544f4b454e5f5452414e534645525f494e5f4641494c45440000000000000000604482015290519081900360640190fd5b601154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015614cca57600080fd5b505afa158015614cde573d6000803e3d6000fd5b505050506040513d6020811015614cf457600080fd5b5051905082811015614d4d576040805162461bcd60e51b815260206004820152601a60248201527f544f4b454e5f5452414e534645525f494e5f4f564552464c4f57000000000000604482015290519081900360640190fd5b9190910395945050505050565b6000806000614d67614f9e565b61255e8686614ec9565b600061123783836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250614f28565b60008184841115614e425760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614e07578181015183820152602001614def565b50505050905090810190601f168015614e345780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b614e52614f9e565b6040518060200160405280614e6b856000015185614d71565b90529392505050565b60008383018285821015610ff85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614e07578181015183820152602001614def565b6000614ed3614f9e565b600080614ee8670de0b6b3a764000087613e88565b90925090506000826003811115614efb57fe5b14614f1a57506040805160208101909152600081529092509050612594565b61258d818660000151613723565b6000831580614f35575082155b15614f4257506000611237565b83830283858281614f4f57fe5b04148390610ff85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614e07578181015183820152602001614def565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ff257805160ff191683800117855561501f565b8280016001018555821561501f579182015b8281111561501f578251825591602001919060010190615004565b5061502b929150615129565b5090565b604080516101208101909152806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160e0810190915280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b610d9b91905b8082111561502b576000815560010161512f56fe6f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e63654345726332303a3a7377656570546f6b656e3a2063616e206e6f7420737765657020756e6465726c79696e6720746f6b656e696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e6f6e6c79207468652061646d696e206d6179207365742074686520636f6d702d6c696b652064656c656761746573657474696e6720696e7465726573742072617465206d6f64656c206661696c65644d494e545f4e45575f4143434f554e545f42414c414e43455f43414c43554c4154494f4e5f4641494c4544626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e636553746f726564496e7465726e616c206661696c656452455041595f424f52524f575f4e45575f4143434f554e545f424f52524f575f42414c414e43455f43414c43554c4154494f4e5f4641494c4544ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef52455041595f424f52524f575f4e45575f544f54414c5f42414c414e43455f43414c43554c4154494f4e5f4641494c45444c49515549444154455f434f4d5054524f4c4c45525f43414c43554c4154455f414d4f554e545f5345495a455f4641494c454465786368616e67655261746553746f7265643a2065786368616e67655261746553746f726564496e7465726e616c206661696c65644d494e545f4e45575f544f54414c5f535550504c595f43414c43554c4154494f4e5f4641494c45446f6e65206f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e206d757374206265207a65726f72656475636520726573657276657320756e657870656374656420756e646572666c6f77a265627a7a72315820952b149004d6331a6bdeb8cd0645bbfd988cf14277209b41ab9c7444e28c7e8364736f6c634300051100326f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e6365696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e73657474696e6720696e7465726573742072617465206d6f64656c206661696c6564608060405234801561001057600080fd5b506105ae806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806309a8acb01461005c578063127ffda01461008a5780635e9a523c146100b657806366331bba146100ee578063fc57d4df1461010a575b600080fd5b6100886004803603604081101561007257600080fd5b506001600160a01b038135169060200135610130565b005b610088600480360360408110156100a057600080fd5b506001600160a01b0381351690602001356101a8565b6100dc600480360360208110156100cc57600080fd5b50356001600160a01b031661028a565b60408051918252519081900360200190f35b6100f66102a9565b604080519115158252519081900360200190f35b6100dc6004803603602081101561012057600080fd5b50356001600160a01b03166102ae565b6001600160a01b038216600081815260208181526040918290205482519384529083015281810183905260608201839052517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a16001600160a01b03909116600090815260208190526040902055565b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156101e357600080fd5b505afa1580156101f7573d6000803e3d6000fd5b505050506040513d602081101561020d57600080fd5b50516001600160a01b038116600081815260208181526040918290205482519384529083015281810185905260608201859052519192507fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae7919081900360800190a16001600160a01b031660009081526020819052604090205550565b6001600160a01b0381166000908152602081905260409020545b919050565b600181565b60006103f5826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156102ec57600080fd5b505afa158015610300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561032957600080fd5b810190808051604051939291908464010000000082111561034957600080fd5b90830190602082018581111561035e57600080fd5b825164010000000081118282018810171561037857600080fd5b82525081516020918201929091019080838360005b838110156103a557818101518382015260200161038d565b50505050905090810190601f1680156103d25780820380516001836020036101000a031916815260200191505b506040818101905260048152630c68aa8960e31b60208201529250610492915050565b156104095750670de0b6b3a76400006102a4565b600080836001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561044557600080fd5b505afa158015610459573d6000803e3d6000fd5b505050506040513d602081101561046f57600080fd5b50516001600160a01b0316815260208101919091526040016000205490506102a4565b6000816040516020018082805190602001908083835b602083106104c75780518252601f1990920191602091820191016104a8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106105355780518252601f199092019160209182019101610516565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fea265627a7a72315820fff67becf40f76918ab8c2a45a608ec37191aa9e6311d4c4b1b9eac5d2b11ed464736f6c6343000511003260806040523480156200001157600080fd5b5060405162005b3038038062005b30833981810160405260208110156200003757600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055615ac6806200006a6000396000f3fe608060405234801561001057600080fd5b506004361061047f5760003560e01c8063741b252511610257578063b30d442711610146578063dce15449116100c3578063e9af029211610087578063e9af02921461141f578063eabe7d9114611445578063ede4edd01461147b578063f4a433c0146114a1578063f851a440146114c75761047f565b8063dce15449146113af578063dcfbc0c7146113db578063e4028eee146113e3578063e6653f3d1461140f578063e8755446146114175761047f565b8063c488847b1161010a578063c488847b14611290578063ca0af043146112df578063cc7ebdc41461130d578063d02f735114611333578063da3d454c146113795761047f565b8063b30d44271461117d578063bb82aa5e14611185578063bdcdc2581461118d578063bea6b8b8146111c9578063c2998238146111ef5761047f565b8063986ab838116101d4578063aa90075411610198578063aa900754146110c1578063abfceffc146110c9578063ac0b0bb71461113f578063b0772d0b14611147578063b21be7fd1461114f5761047f565b8063986ab83814610ea45780639d1b5a0a14610eca578063a76b3fda14610ed2578063a7f0e23114610ef8578063a8b4394814610f1c5761047f565b80638e8f294b1161021b5780638e8f294b14610de15780638ebf636414610e29578063929fe9a114610e4857806394543c1514610e7657806394b2294b14610e9c5761047f565b8063741b252514610d5f5780637dc0d1d014610d8557806387495bad14610d8d57806387f7630314610db35780638c57804e14610dbb5761047f565b80634ada90af116103735780635f5af1aa116102f05780636aa875b5116102b45780636aa875b514610c595780636b79c38d14610c7f5780636d154ea514610ccd5780636d35bf9114610cf3578063731f0c2b14610d395761047f565b80635f5af1aa146109c75780635fc7e71e146109ed578063607ef6c114610a335780636810dfa614610af15780636a56947e14610c1d5761047f565b806352d84d1e1161033757806352d84d1e146108fc57806355ee1fe114610919578063598ee1cb1461093f5780635c7786051461096b5780635ec88c79146109a15761047f565b80634ada90af1461080b5780634e79238f146108135780634ef4c3e11461086d5780634fd42e17146108a357806351dff989146108c05761047f565b806327efe3cb116104015780633c94786f116103c55780633c94786f1461074d57806341c728b91461075557806342cbb15c1461079157806347ef3b3b146107995780634a584432146107e55761047f565b806327efe3cb146106915780632d70db78146106bd578063317b0b77146106dc578063391957d7146106f95780633bcf7ec11461071f5761047f565b80631ededc91116104485780631ededc91146105df57806321af45691461062157806324008a621461064557806324a3d6221461068157806326782247146106895761047f565b80627e3dd21461048457806318c882a5146104a05780631c3db2e0146104ce5780631d504dc6146105815780631d7b33d7146105a7575b600080fd5b61048c6114cf565b604080519115158252519081900360200190f35b61048c600480360360408110156104b657600080fd5b506001600160a01b03813516906020013515156114d4565b61057f600480360360408110156104e457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561050e57600080fd5b82018360208201111561052057600080fd5b803590602001918460208302840111600160201b8311171561054157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611674945050505050565b005b61057f6004803603602081101561059757600080fd5b50356001600160a01b03166116d6565b6105cd600480360360208110156105bd57600080fd5b50356001600160a01b0316611890565b60408051918252519081900360200190f35b61057f600480360360a08110156105f557600080fd5b506001600160a01b038135811691602081013582169160408201351690606081013590608001356118a2565b6106296118a7565b604080516001600160a01b039092168252519081900360200190f35b6105cd6004803603608081101561065b57600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356118b6565b61062961197d565b61062961198c565b61057f600480360360408110156106a757600080fd5b506001600160a01b03813516906020013561199b565b61048c600480360360208110156106d357600080fd5b50351515611a9e565b6105cd600480360360208110156106f257600080fd5b5035611bd8565b61057f6004803603602081101561070f57600080fd5b50356001600160a01b0316611c85565b61048c6004803603604081101561073557600080fd5b506001600160a01b0381351690602001351515611d31565b61048c611ecc565b61057f6004803603608081101561076b57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611edc565b6105cd611ee2565b61057f600480360360c08110156107af57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135611ee7565b6105cd600480360360208110156107fb57600080fd5b50356001600160a01b0316611eef565b6105cd611f01565b61084f6004803603608081101561082957600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611f07565b60408051938452602084019290925282820152519081900360600190f35b6105cd6004803603606081101561088357600080fd5b506001600160a01b03813581169160208101359091169060400135611f41565b6105cd600480360360208110156108b957600080fd5b5035611fe7565b61057f600480360360808110156108d657600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612057565b6106296004803603602081101561091257600080fd5b50356120ab565b6105cd6004803603602081101561092f57600080fd5b50356001600160a01b03166120d2565b61057f6004803603604081101561095557600080fd5b506001600160a01b038135169060200135612157565b61057f6004803603606081101561098157600080fd5b506001600160a01b03813581169160208101359091169060400135612252565b61084f600480360360208110156109b757600080fd5b50356001600160a01b0316612257565b6105cd600480360360208110156109dd57600080fd5b50356001600160a01b031661228c565b6105cd600480360360a0811015610a0357600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135612310565b61057f60048036036040811015610a4957600080fd5b810190602081018135600160201b811115610a6357600080fd5b820183602082011115610a7557600080fd5b803590602001918460208302840111600160201b83111715610a9657600080fd5b919390929091602081019035600160201b811115610ab357600080fd5b820183602082011115610ac557600080fd5b803590602001918460208302840111600160201b83111715610ae657600080fd5b5090925090506124c7565b61057f60048036036080811015610b0757600080fd5b810190602081018135600160201b811115610b2157600080fd5b820183602082011115610b3357600080fd5b803590602001918460208302840111600160201b83111715610b5457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ba357600080fd5b820183602082011115610bb557600080fd5b803590602001918460208302840111600160201b83111715610bd657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050803515159150602001351515612657565b61057f60048036036080811015610c3357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611edc565b6105cd60048036036020811015610c6f57600080fd5b50356001600160a01b03166128a2565b610ca560048036036020811015610c9557600080fd5b50356001600160a01b03166128b4565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61048c60048036036020811015610ce357600080fd5b50356001600160a01b03166128de565b61057f600480360360a0811015610d0957600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356118a2565b61048c60048036036020811015610d4f57600080fd5b50356001600160a01b03166128f3565b61057f60048036036020811015610d7557600080fd5b50356001600160a01b0316612908565b6106296129cb565b6105cd60048036036020811015610da357600080fd5b50356001600160a01b03166129da565b61048c6129f2565b610ca560048036036020811015610dd157600080fd5b50356001600160a01b0316612a02565b610e0760048036036020811015610df757600080fd5b50356001600160a01b0316612a2c565b6040805193151584526020840192909252151582820152519081900360600190f35b61048c60048036036020811015610e3f57600080fd5b50351515612a52565b61048c60048036036040811015610e5e57600080fd5b506001600160a01b0381358116916020013516612b8b565b61048c60048036036020811015610e8c57600080fd5b50356001600160a01b0316612bbe565b6105cd612c80565b6105cd60048036036020811015610eba57600080fd5b50356001600160a01b0316612c86565b610629612c98565b6105cd60048036036020811015610ee857600080fd5b50356001600160a01b0316612cb0565b610f00612e15565b604080516001600160e01b039092168252519081900360200190f35b61057f60048036036060811015610f3257600080fd5b810190602081018135600160201b811115610f4c57600080fd5b820183602082011115610f5e57600080fd5b803590602001918460208302840111600160201b83111715610f7f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610fce57600080fd5b820183602082011115610fe057600080fd5b803590602001918460208302840111600160201b8311171561100157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561105057600080fd5b82018360208201111561106257600080fd5b803590602001918460208302840111600160201b8311171561108357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612e27945050505050565b6105cd612f24565b6110ef600480360360208110156110df57600080fd5b50356001600160a01b0316612f2a565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561112b578181015183820152602001611113565b505050509050019250505060405180910390f35b61048c612fb3565b6110ef612fc3565b6105cd6004803603604081101561116557600080fd5b506001600160a01b0381358116916020013516613025565b61057f613042565b610629613306565b6105cd600480360360808110156111a357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135613315565b6105cd600480360360208110156111df57600080fd5b50356001600160a01b03166133a5565b6110ef6004803603602081101561120557600080fd5b810190602081018135600160201b81111561121f57600080fd5b82018360208201111561123157600080fd5b803590602001918460208302840111600160201b8311171561125257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506133b7945050505050565b6112c6600480360360608110156112a657600080fd5b506001600160a01b0381358116916020810135909116906040013561344e565b6040805192835260208301919091528051918290030190f35b6105cd600480360360408110156112f557600080fd5b506001600160a01b0381358116916020013516613676565b6105cd6004803603602081101561132357600080fd5b50356001600160a01b0316613693565b6105cd600480360360a081101561134957600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356136a5565b6105cd6004803603606081101561138f57600080fd5b506001600160a01b03813581169160208101359091169060400135613859565b610629600480360360408110156113c557600080fd5b506001600160a01b038135169060200135613c3b565b610629613c70565b6105cd600480360360408110156113f957600080fd5b506001600160a01b038135169060200135613c7f565b61048c613e2f565b6105cd613e3f565b61057f6004803603602081101561143557600080fd5b50356001600160a01b0316613e45565b6105cd6004803603606081101561145b57600080fd5b506001600160a01b03813581169160208101359091169060400135613eac565b6105cd6004803603602081101561149157600080fd5b50356001600160a01b0316613ee7565b6105cd600480360360208110156114b757600080fd5b50356001600160a01b03166141fa565b61062961420c565b600181565b6001600160a01b03821660009081526009602052604081205460ff1661152b5760405162461bcd60e51b815260040180806020018281038252602881526020018061594b6028913960400191505060405180910390fd5b600a546001600160a01b031633148061154e57506000546001600160a01b031633145b6115895760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b03163314806115a457506001821515145b6115ee576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b6001600160a01b0383166000818152600c6020908152604091829020805486151560ff199091168117909155825193845283830152606090830181905260069083015265426f72726f7760d01b6080830152517f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09181900360a00190a150805b92915050565b6040805160018082528183019092526060916020808301908038833901905050905082816000815181106116a457fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506116d18183600180612657565b505050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b50516001600160a01b031633146117815760405162461bcd60e51b8152600401808060200182810382526027815260200180615a6b6027913960400191505060405180910390fd5b806001600160a01b031663c1e803346040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156117bc57600080fd5b505af11580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b50511561183a576040805162461bcd60e51b815260206004820152601560248201527f6368616e6765206e6f7420617574686f72697a65640000000000000000000000604482015290519081900360640190fd5b806001600160a01b031663b30d44276040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561187557600080fd5b505af1158015611889573d6000803e3d6000fd5b5050505050565b600f6020526000908152604090205481565b611889565b6015546001600160a01b031681565b6001600160a01b03841660009081526009602052604081205460ff166118de57506009611975565b6118e661588b565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561192a57600080fd5b505afa15801561193e573d6000803e3d6000fd5b505050506040513d602081101561195457600080fd5b505190529050611964868261421b565b61196f8685836143f3565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b6119a3614586565b6119f4576040805162461bcd60e51b815260206004820152601960248201527f6f6e6c792061646d696e2063616e206772616e7420636f6d7000000000000000604482015290519081900360640190fd5b6000611a0083836145af565b90508015611a55576040805162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e7420636f6d7020666f72206772616e740000000000604482015290519081900360640190fd5b604080516001600160a01b03851681526020810184905281517f98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c929181900390910190a1505050565b600a546000906001600160a01b0316331480611ac457506000546001600160a01b031633145b611aff5760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480611b1a57506001821515145b611b64576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b600a8054831515600160b81b810260ff60b81b1990921691909117909155604080516020810192909252808252600582820152645365697a6560d81b6060830152517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de09181900360800190a150805b919050565b600080546001600160a01b03163314611c38576040805162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f7200604482015290519081900360640190fd5b6005805490839055604080518281526020810185905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a160005b9392505050565b6000546001600160a01b03163314611cce5760405162461bcd60e51b81526004018080602001828103825260268152602001806159c26026913960400191505060405180910390fd5b601580546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935281517feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29929181900390910190a15050565b6001600160a01b03821660009081526009602052604081205460ff16611d885760405162461bcd60e51b815260040180806020018281038252602881526020018061594b6028913960400191505060405180910390fd5b600a546001600160a01b0316331480611dab57506000546001600160a01b031633145b611de65760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480611e0157506001821515145b611e4b576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b6001600160a01b0383166000818152600b6020908152604091829020805486151560ff199091168117909155825193845283830152606090830181905260049083015263135a5b9d60e21b6080830152517f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09181900360a00190a150919050565b600a54600160a01b900460ff1681565b50505050565b435b90565b505050505050565b60166020526000908152604090205481565b60065481565b600080600080600080611f1c8a8a8a8a6146e9565b925092509250826011811115611f2e57fe5b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600b602052604081205460ff1615611fa0576040805162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b604482015290519081900360640190fd5b6001600160a01b03841660009081526009602052604090205460ff16611fca5760095b9050611c7e565b611fd384614a21565b611fdd8484614bb5565b6000949350505050565b600080546001600160a01b0316331461200d576120066001600b614d70565b9050611bd3565b6006805490839055604080518281526020810185905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611c7e565b801580156120655750600082115b15611edc576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d81815481106120b857fe5b6000918252602090912001546001600160a01b0316905081565b600080546001600160a01b031633146120f15761200660016010614d70565b600480546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611c7e565b61215f614586565b6121b0576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792061646d696e2063616e2073657420636f6d70207370656564000000604482015290519081900360640190fd5b6121b982612908565b806121dc576001600160a01b0382166000908152601860205260408120556121fe565b6121e4611ee2565b6001600160a01b0383166000908152601860205260409020555b6001600160a01b038216600081815260176020908152604091829020849055815184815291517f386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b39281900390910190a25050565b6116d1565b60008060008060008061226e8760008060006146e9565b92509250925082601181111561228057fe5b97919650945092505050565b600080546001600160a01b031633146122ab5761200660016013614d70565b600a80546001600160a01b038481166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9281900390910190a16000611c7e565b6001600160a01b03851660009081526009602052604081205460ff16158061235157506001600160a01b03851660009081526009602052604090205460ff16155b156123605760095b90506124be565b6000866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123b857600080fd5b505afa1580156123cc573d6000803e3d6000fd5b505050506040513d60208110156123e257600080fd5b505190506123ef87612bbe565b1561243857828110156124335760405162461bcd60e51b81526004018080602001828103825260288152602001806159736028913960400191505060405180910390fd5b6124b8565b60008061244486614dd6565b9193509091506000905082601181111561245a57fe5b146124755781601181111561246b57fe5b93505050506124be565b8061248157600361246b565b600061249d604051806020016040528060055481525085614df6565b9050808611156124b45760119450505050506124be565b5050505b60009150505b95945050505050565b6000546001600160a01b03163314806124ea57506015546001600160a01b031633145b6125255760405162461bcd60e51b81526004018080602001828103825260358152602001806159e86035913960400191505060405180910390fd5b8281811580159061253557508082145b612576576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b8281101561264e5784848281811061258d57fe5b90506020020135601660008989858181106125a457fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106125e457fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f686868481811061262a57fe5b905060200201356040518082815260200191505060405180910390a2600101612579565b50505050505050565b60005b835181101561280457600084828151811061267157fe5b6020908102919091018101516001600160a01b0381166000908152600990925260409091205490915060ff166126ee576040805162461bcd60e51b815260206004820152601560248201527f6d61726b6574206d757374206265206c69737465640000000000000000000000604482015290519081900360640190fd5b600184151514156127b45761270161588b565b6040518060200160405280836001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561274557600080fd5b505afa158015612759573d6000803e3d6000fd5b505050506040513d602081101561276f57600080fd5b50519052905061277f828261421b565b60005b87518110156127b1576127a98389838151811061279b57fe5b6020026020010151846143f3565b600101612782565b50505b600183151514156127fb576127c881614a21565b60005b86518110156127f9576127f1828883815181106127e457fe5b6020026020010151614bb5565b6001016127cb565b505b5060010161265a565b5060005b84518110156118895761286685828151811061282057fe5b60200260200101516014600088858151811061283857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546145af565b6014600087848151811061287657fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101612808565b601a6020526000908152604090205481565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b600c6020526000908152604090205460ff1681565b600b6020526000908152604090205460ff1681565b6001600160a01b0381166000908152601760205260408120549061292a611ee2565b6001600160a01b03841660009081526018602052604081205491925090612952908390614e15565b90506000811180156129645750600083115b15611edc5760006129758285614e57565b6001600160a01b0386166000908152601460205260408120549192509061299c9083614e99565b6001600160a01b0387166000908152601460209081526040808320939093556018905220849055505050505050565b6004546001600160a01b031681565b6000816129e78133614ecf565b6011811115611c7e57fe5b600a54600160b01b900460ff1681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b600a546000906001600160a01b0316331480612a7857506000546001600160a01b031633145b612ab35760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480612ace57506001821515145b612b18576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b600a8054831515600160b01b810260ff60b01b1990921691909117909155604080516020810192909252808252600882820152672a3930b739b332b960c11b6060830152517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de09181900360800190a15090565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff1692915050565b6001600160a01b038116600090815260096020526040812060010154158015612c0457506001600160a01b0382166000908152600c602052604090205460ff1615156001145b801561166e5750816001600160a01b031663173b99046040518163ffffffff1660e01b815260040160206040518083038186803b158015612c4457600080fd5b505afa158015612c58573d6000803e3d6000fd5b505050506040513d6020811015612c6e57600080fd5b5051670de0b6b3a76400001492915050565b60075481565b60176020526000908152604090205481565b73c00e94cb662c3520282e6f5717214004a7f2688890565b600080546001600160a01b03163314612ccf5761200660016012614d70565b6001600160a01b03821660009081526009602052604090205460ff1615612cfc57612006600a6011614d70565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d3557600080fd5b505afa158015612d49573d6000803e3d6000fd5b505050506040513d6020811015612d5f57600080fd5b5050604080516060810182526001808252600060208381018281528486018381526001600160a01b03891684526009909252949091209251835490151560ff19918216178455935191830191909155516003909101805491151591909216179055612dc982614fc5565b612dd2826150ac565b604080516001600160a01b038416815290517fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f9181900360200190a1600061166e565b6a0c097ce7bc90715b34b9f160241b81565b612e2f614586565b612e80576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792061646d696e2063616e2073657420636f6d70207370656564000000604482015290519081900360640190fd5b8251825181148015612e925750815181145b612ecd5760405162461bcd60e51b8152600401808060200182810382526029815260200180615a426029913960400191505060405180910390fd5b60005b8181101561188957612f1c858281518110612ee757fe5b6020026020010151858381518110612efb57fe5b6020026020010151858481518110612f0f57fe5b602002602001015161516a565b600101612ed0565b600e5481565b60608060086000846001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612fa657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f88575b5093979650505050505050565b600a54600160b81b900460ff1681565b6060600d80548060200260200160405190810160405280929190818152602001828054801561301b57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612ffd575b5050505050905090565b601260209081526000928352604080842090915290825290205481565b6002546001600160a01b031633146130a1576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c7920627261696e732063616e206265636f6d6520697473656c66000000604482015290519081900360640190fd5b60006130e96130ae611ee2565b6040518060400160405280601c81526020017f626c6f636b206e756d626572206578636565647320333220626974730000000081525061534d565b905060005b600d5481101561330257600f6000600d838154811061310957fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002054601a6000600d848154811061315957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120829055600d805460199291908590811061319357fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812091909155600d8054600f929190849081106131ce57fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120819055600d805460109183918590811061320857fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120600d80549193506011918391908690811061324357fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902082549091506001600160e01b03166132b157815463ffffffff8516600160e01b026001600160e01b03199091166a0c097ce7bc90715b34b9f160241b176001600160e01b03161782555b80546001600160e01b03166132f857805463ffffffff8516600160e01b026001600160e01b03199091166a0c097ce7bc90715b34b9f160241b176001600160e01b03161781555b50506001016130ee565b5050565b6002546001600160a01b031681565b600a54600090600160b01b900460ff161561336c576040805162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b604482015290519081900360640190fd5b60006133798686856153e7565b90508015613388579050611975565b61339186614a21565b61339b8686614bb5565b61196f8685614bb5565b60186020526000908152604090205481565b60606000825190506060816040519080825280602002602001820160405280156133eb578160200160208202803883390190505b50905060005b8281101561344657600085828151811061340757fe5b6020026020010151905061341b8133614ecf565b601181111561342657fe5b83838151811061343257fe5b6020908102919091010152506001016133f1565b509392505050565b600480546040805163fc57d4df60e01b81526001600160a01b038781169482019490945290516000938493849391169163fc57d4df91602480820192602092909190829003018186803b1580156134a457600080fd5b505afa1580156134b8573d6000803e3d6000fd5b505050506040513d60208110156134ce57600080fd5b5051600480546040805163fc57d4df60e01b81526001600160a01b038a8116948201949094529051939450600093929091169163fc57d4df91602480820192602092909190829003018186803b15801561352757600080fd5b505afa15801561353b573d6000803e3d6000fd5b505050506040513d602081101561355157600080fd5b50519050811580613560575080155b1561357557600d93506000925061366e915050565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156135b057600080fd5b505afa1580156135c4573d6000803e3d6000fd5b505050506040513d60208110156135da57600080fd5b5051905060006135e861588b565b6135f061588b565b6135f861588b565b613620604051806020016040528060065481525060405180602001604052808a815250615493565b9250613648604051806020016040528088815250604051806020016040528088815250615493565b915061365483836154d2565b9050613660818b614df6565b600099509750505050505050505b935093915050565b601360209081526000928352604080842090915290825290205481565b60146020526000908152604090205481565b600a54600090600160b81b900460ff16156136f9576040805162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b604482015290519081900360640190fd5b6001600160a01b03861660009081526009602052604090205460ff16158061373a57506001600160a01b03851660009081526009602052604090205460ff16155b15613746576009612359565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561377f57600080fd5b505afa158015613793573d6000803e3d6000fd5b505050506040513d60208110156137a957600080fd5b505160408051635fe3b56760e01b815290516001600160a01b0392831692891691635fe3b567916004808301926020929190829003018186803b1580156137ef57600080fd5b505afa158015613803573d6000803e3d6000fd5b505050506040513d602081101561381957600080fd5b50516001600160a01b031614613830576002612359565b61383986614a21565b6138438684614bb5565b61384d8685614bb5565b60009695505050505050565b6001600160a01b0383166000908152600c602052604081205460ff16156138ba576040805162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03841660009081526009602052604090205460ff166138e1576009611fc3565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166139d957336001600160a01b0385161461396f576040805162461bcd60e51b815260206004820152601560248201527f73656e646572206d7573742062652063546f6b656e0000000000000000000000604482015290519081900360640190fd5b600061397b3385614ecf565b9050600081601181111561398b57fe5b146139a45780601181111561399c57fe5b915050611c7e565b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff166139d757fe5b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015613a2a57600080fd5b505afa158015613a3e573d6000803e3d6000fd5b505050506040513d6020811015613a5457600080fd5b5051613a6157600d611fc3565b6001600160a01b0384166000908152601660205260409020548015613b4e576000856001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015613abb57600080fd5b505afa158015613acf573d6000803e3d6000fd5b505050506040513d6020811015613ae557600080fd5b505190506000613af58286614e99565b9050828110613b4b576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b50505b600080613b5e86886000886146e9565b91935090915060009050826011811115613b7457fe5b14613b8f57816011811115613b8557fe5b9350505050611c7e565b8015613b9c576004613b85565b613ba461588b565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613be857600080fd5b505afa158015613bfc573d6000803e3d6000fd5b505050506040513d6020811015613c1257600080fd5b505190529050613c22888261421b565b613c2d8888836143f3565b600098975050505050505050565b60086020528160005260406000208181548110613c5457fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b600080546001600160a01b03163314613ca557613c9e60016006614d70565b905061166e565b6001600160a01b0383166000908152600960205260409020805460ff16613cda57613cd260096007614d70565b91505061166e565b613ce261588b565b506040805160208101909152838152613cf961588b565b506040805160208101909152670c7d713b49da00008152613d1a818361550e565b15613d3557613d2b60066008614d70565b935050505061166e565b8415801590613dbe5750600480546040805163fc57d4df60e01b81526001600160a01b038a8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015613d9057600080fd5b505afa158015613da4573d6000803e3d6000fd5b505050506040513d6020811015613dba57600080fd5b5051155b15613dcf57613d2b600d6009614d70565b60018301805490869055604080516001600160a01b03891681526020810183905280820188905290517f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59181900360600190a16000979650505050505050565b600a54600160a81b900460ff1681565b60055481565b613ea981600d805480602002602001604051908101604052809291908181526020018280548015613e9f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613e81575b5050505050611674565b50565b600080613eba8585856153e7565b90508015613ec9579050611c7e565b613ed285614a21565b613edc8585614bb5565b600095945050505050565b6000808290506000806000836001600160a01b031663c37f68e2336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b158015613f4857600080fd5b505afa158015613f5c573d6000803e3d6000fd5b505050506040513d6080811015613f7257600080fd5b508051602082015160409092015190945090925090508215613fc55760405162461bcd60e51b8152600401808060200182810382526025815260200180615a1d6025913960400191505060405180910390fd5b8015613fe257613fd7600c6002614d70565b945050505050611bd3565b6000613fef8733856153e7565b9050801561401057614004600e600383615515565b95505050505050611bd3565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff1661404f5760009650505050505050611bd3565b3360009081526002820160209081526040808320805460ff1916905560088252918290208054835181840281018401909452808452606093928301828280156140c157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116140a3575b5050835193945083925060009150505b8281101561411657896001600160a01b03168482815181106140ef57fe5b60200260200101516001600160a01b0316141561410e57809150614116565b6001016140d1565b5081811061412057fe5b33600090815260086020526040902080548190600019810190811061414157fe5b9060005260206000200160009054906101000a90046001600160a01b031681838154811061416b57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905580546141a482600019830161589e565b50604080516001600160a01b038c16815233602082015281517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a160009c9b505050505050505050505050565b60196020526000908152604090205481565b6000546001600160a01b031681565b6001600160a01b03821660009081526011602090815260408083206019909252822054909161424b6130ae611ee2565b835490915060009061426d9063ffffffff80851691600160e01b900416614e15565b905060008111801561427f5750600083115b156143c85760006142f4876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156142c257600080fd5b505afa1580156142d6573d6000803e3d6000fd5b505050506040513d60208110156142ec57600080fd5b50518761557b565b905060006143028386614e57565b905061430c61588b565b600083116143295760405180602001604052806000815250614333565b6143338284615599565b604080516020810190915288546001600160e01b031681529091506143969061435c90836155cd565b5160408051808201909152601a81527f6e657720696e646578206578636565647320323234206269747300000000000060208201526155f2565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611ee7915050565b8015611ee757835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b6001600160a01b03838116600090815260116020908152604080832080546013845282852095881685529490925290912080546001600160e01b039093169081905590918015801561445257506a0c097ce7bc90715b34b9f160241b82115b1561446857506a0c097ce7bc90715b34b9f160241b5b61447061588b565b60405180602001604052806144858585614e15565b815250905060006144e5886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156142c257600080fd5b905060006144f38284615647565b6001600160a01b0389166000908152601460205260408120549192509061451a9083614e99565b6001600160a01b03808b1660008181526014602090815260409182902085905581518781529081018b905281519495509193928e16927f1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a69281900390910190a350505050505050505050565b600080546001600160a01b03163314806145aa57506002546001600160a01b031633145b905090565b6000806145ba612c98565b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561460657600080fd5b505afa15801561461a573d6000803e3d6000fd5b505050506040513d602081101561463057600080fd5b5051905083158015906146435750808411155b156146e057816001600160a01b031663a9059cbb86866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156146a857600080fd5b505af11580156146bc573d6000803e3d6000fd5b505050506040513d60208110156146d257600080fd5b506000935061166e92505050565b50919392505050565b60008060006146f66158c2565b6001600160a01b0388166000908152600860209081526040808320805482518185028101850190935280835260609383018282801561475e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614740575b50939450600093505050505b81518110156149e257600082828151811061478157fe5b60200260200101519050806001600160a01b031663c37f68e28d6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b1580156147e157600080fd5b505afa1580156147f5573d6000803e3d6000fd5b505050506040513d608081101561480b57600080fd5b508051602082015160408084015160609485015160808b01529389019390935291870191909152935083156148505750600f965060009550859450611f379350505050565b60408051602080820183526001600160a01b0380851660008181526009845285902060010154845260c08a01939093528351808301855260808a0151815260e08a015260048054855163fc57d4df60e01b815291820194909452935192169263fc57d4df9260248083019392829003018186803b1580156148d057600080fd5b505afa1580156148e4573d6000803e3d6000fd5b505050506040513d60208110156148fa57600080fd5b505160a0860181905261491d5750600d965060009550859450611f379350505050565b604080516020810190915260a0860151815261010086015260c085015160e08601516149579161494c91615493565b866101000151615493565b610120860181905260408601518651614971929190615675565b85526101008501516060860151602087015161498e929190615675565b60208601526001600160a01b03818116908c1614156149d9576149bb8561012001518b8760200151615675565b602086018190526101008601516149d3918b90615675565b60208601525b5060010161476a565b50602083015183511115614a085750506020810151905160009450039150829050611f37565b5050805160209091015160009450849350039050611f37565b6001600160a01b0381166000908152601060209081526040808320601a9092528220549091614a516130ae611ee2565b8354909150600090614a739063ffffffff80851691600160e01b900416614e15565b9050600081118015614a855750600083115b15614b8b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015614ac557600080fd5b505afa158015614ad9573d6000803e3d6000fd5b505050506040513d6020811015614aef57600080fd5b505190506000614aff8386614e57565b9050614b0961588b565b60008311614b265760405180602001604052806000815250614b30565b614b308284615599565b604080516020810190915288546001600160e01b03168152909150614b599061435c90836155cd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611889915050565b801561188957835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b6001600160a01b03828116600090815260106020908152604080832080546012845282852095871685529490925290912080546001600160e01b0390931690819055909180158015614c1457506a0c097ce7bc90715b34b9f160241b82115b15614c2a57506a0c097ce7bc90715b34b9f160241b5b614c3261588b565b6040518060200160405280614c478585614e15565b81525090506000866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015614ca457600080fd5b505afa158015614cb8573d6000803e3d6000fd5b505050506040513d6020811015614cce57600080fd5b505190506000614cde8284615647565b6001600160a01b03881660009081526014602052604081205491925090614d059083614e99565b6001600160a01b03808a1660008181526014602090815260409182902085905581518781529081018b905281519495509193928d16927f2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a9281900390910190a3505050505050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836011811115614d9f57fe5b836013811115614dab57fe5b604080519283526020830191909152600082820152519081900360600190a1826011811115611c7e57fe5b6000806000614de98460008060006146e9565b9250925092509193909250565b6000614e0061588b565b614e0a848461569d565b9050611975816156be565b6000611c7e83836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f7700000000000000000000008152506156cd565b6000611c7e83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250615727565b6000611c7e8383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506157a6565b6001600160a01b0382166000908152600960205260408120805460ff16614efa57600991505061166e565b6001600160a01b038316600090815260028201602052604090205460ff16151560011415614f2c57600091505061166e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff19166001908117909155600883528184208054918201815584529282902090920180549489166001600160a01b031990951685179055815193845283019190915280517f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59281900390910190a15060009392505050565b60005b600d5481101561505957816001600160a01b0316600d8281548110614fe957fe5b6000918252602090912001546001600160a01b03161415615051576040805162461bcd60e51b815260206004820152601460248201527f6d61726b657420616c7265616479206164646564000000000000000000000000604482015290519081900360640190fd5b600101614fc8565b50600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006150b96130ae611ee2565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b031661510f5781546001600160e01b0319166a0c097ce7bc90715b34b9f160241b1782555b80546001600160e01b031661513d5780546001600160e01b0319166a0c097ce7bc90715b34b9f160241b1781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6001600160a01b0383166000908152600960205260409020805460ff166151d8576040805162461bcd60e51b815260206004820152601960248201527f636f6d70206d61726b6574206973206e6f74206c697374656400000000000000604482015290519081900360640190fd5b6001600160a01b0384166000908152601a602052604090205483146152515761520084614a21565b6001600160a01b0384166000818152601a6020908152604091829020869055815186815291517fdeafccd0c0b768b2529f7dcbbe58e155d6023059150b7490ed4535cc3744b92d9281900390910190a25b6001600160a01b0384166000908152601960205260409020548214611edc5761527861588b565b6040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156152bc57600080fd5b505afa1580156152d0573d6000803e3d6000fd5b505050506040513d60208110156152e657600080fd5b5051905290506152f6858261421b565b6001600160a01b038516600081815260196020908152604091829020869055815186815291517f20af8e791cc98f74b2d7a391c80980ca8e5aebf3d4060bf581997b6acae2e5379281900390910190a25050505050565b600081600160201b84106153df5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156153a457818101518382015260200161538c565b50505050905090810190601f1680156153d15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b6001600160a01b03831660009081526009602052604081205460ff1661540e576009611fc3565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16615446576000611fc3565b60008061545685878660006146e9565b9193509091506000905082601181111561546c57fe5b146154865781601181111561547d57fe5b92505050611c7e565b801561384d57600461547d565b61549b61588b565b6040518060200160405280670de0b6b3a76400006154c186600001518660000151614e57565b816154c857fe5b0490529392505050565b6154da61588b565b60405180602001604052806155056154fe8660000151670de0b6b3a7640000614e57565b85516157fb565b90529392505050565b5190511090565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa084601181111561554457fe5b84601381111561555057fe5b604080519283526020830191909152818101859052519081900360600190a183601181111561197557fe5b6000611c7e61559284670de0b6b3a7640000614e57565b83516157fb565b6155a161588b565b60405180602001604052806155056155c7866a0c097ce7bc90715b34b9f160241b614e57565b856157fb565b6155d561588b565b604051806020016040528061550585600001518560000151614e99565b600081600160e01b84106153df5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b60006a0c097ce7bc90715b34b9f160241b615666848460000151614e57565b8161566d57fe5b049392505050565b600061567f61588b565b615689858561569d565b90506124be615697826156be565b84614e99565b6156a561588b565b6040518060200160405280615505856000015185614e57565b51670de0b6b3a7640000900490565b6000818484111561571f5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b505050900390565b6000831580615734575082155b1561574157506000611c7e565b8383028385828161574e57fe5b0414839061579d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b50949350505050565b6000838301828582101561579d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b6000611c7e83836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250600081836158785760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b5082848161588257fe5b04949350505050565b6040518060200160405280600081525090565b8154818355818111156116d1576000838152602090206116d191810190830161592c565b60405180610140016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200161590061588b565b815260200161590d61588b565b815260200161591a61588b565b815260200161592761588b565b905290565b611ee491905b808211156159465760008155600101615932565b509056fe63616e6e6f742070617573652061206d61726b65742074686174206973206e6f74206c697374656443616e206e6f74207265706179206d6f7265207468616e2074686520746f74616c20626f72726f776f6e6c7920706175736520677561726469616e20616e642061646d696e2063616e2070617573656f6e6c792061646d696e2063616e2073657420626f72726f772063617020677561726469616e6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616e2063616e2073657420626f72726f772063617073657869744d61726b65743a206765744163636f756e74536e617073686f74206661696c6564436f6d7074726f6c6c65723a3a5f736574436f6d7053706565647320696e76616c696420696e7075746f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676520627261696e73a265627a7a7231582091615208ad105512182c4a963efbeeaaba2af6637d5296462959dea57e6ac6db64736f6c63430005110032608060405234801561001057600080fd5b50604051610a9a380380610a9a833981810160405260a081101561003357600080fd5b508051602082015160408301516060840151608090940151600080546001600160a01b0319166001600160a01b03831617905592939192909190848484848461007e8585858561008d565b505050505050505050506102bc565b6100a7622014808561017060201b6105f41790919060201c565b6002556100f66100c562201480836101c1602090811b61059b17901c565b6100e4670de0b6b3a7640000866101c160201b61059b1790919060201c565b61017060201b6105f41790919060201c565b6001556101118262201480610170602090811b6105f417901c565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b60006101b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061021a60201b60201c565b90505b92915050565b6000826101d0575060006101bb565b828202828482816101dd57fe5b04146101b85760405162461bcd60e51b8152600401808060200182810382526021815260200180610a796021913960400191505060405180910390fd5b600081836102a65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026b578181015183820152602001610253565b50505050905090810190601f1680156102985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816102b257fe5b0495945050505050565b6107ae806102cb6000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c80638da5cb5b11610081578063b9f9850a1161005b578063b9f9850a146101eb578063f14039de146101f3578063fd2da339146101fb576100b9565b80638da5cb5b14610190578063a385fb96146101b4578063b8168816146101bc576100b9565b806315f24053146100be5780632037f3e7146101005780632191f92a146101315780636e71e2d81461014d5780638726bb8914610188575b600080fd5b6100e7600480360360608110156100d457600080fd5b5080359060208101359060400135610203565b6040805192835260208301919091528051918290030190f35b61012f6004803603608081101561011657600080fd5b508035906020810135906040810135906060013561021f565b005b61013961027a565b604080519115158252519081900360200190f35b6101766004803603606081101561016357600080fd5b508035906020810135906040013561027f565b60408051918252519081900360200190f35b6101766102df565b6101986102e5565b604080516001600160a01b039092168252519081900360200190f35b6101766102f4565b610176600480360360808110156101d257600080fd5b50803590602081013590604081013590606001356102fb565b61017661037a565b610176610380565b610176610386565b600080600061021386868661038c565b90969095509350505050565b6000546001600160a01b031633146102685760405162461bcd60e51b81526004018080602001828103825260268152602001806107546026913960400191505060405180910390fd5b61027484848484610455565b50505050565b600181565b60008261028e575060006102d8565b6102d56102b1836102a5878763ffffffff6104f616565b9063ffffffff61055916565b6102c985670de0b6b3a764000063ffffffff61059b16565b9063ffffffff6105f416565b90505b9392505050565b60015481565b6000546001600160a01b031681565b6220148081565b600080610316670de0b6b3a76400008463ffffffff61055916565b9050600061032587878761038c565b90506000610345670de0b6b3a76400006102c9848663ffffffff61059b16565b905061036e670de0b6b3a76400006102c9836103628c8c8c61027f565b9063ffffffff61059b16565b98975050505050505050565b60035481565b60025481565b60045481565b60008061039a85858561027f565b905060045481116103e0576103d86002546103cc670de0b6b3a76400006102c96001548661059b90919063ffffffff16565b9063ffffffff6104f616565b9150506102d8565b600061040b6002546103cc670de0b6b3a76400006102c960015460045461059b90919063ffffffff16565b905060006104246004548461055990919063ffffffff16565b905061044b826103cc670de0b6b3a76400006102c96003548661059b90919063ffffffff16565b93505050506102d8565b610468846220148063ffffffff6105f416565b6002556104816102b1622014808363ffffffff61059b16565b600155610497826220148063ffffffff6105f416565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b600082820183811015610550576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061055083836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250610636565b6000826105aa57506000610553565b828202828482816105b757fe5b04146105505760405162461bcd60e51b81526004018080602001828103825260218152602001806107336021913960400191505060405180910390fd5b600061055083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506106cd565b600081848411156106c55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561068a578181015183820152602001610672565b50505050905090810190601f1680156106b75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000818361071c5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561068a578181015183820152602001610672565b50600083858161072857fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776f6e6c7920746865206f776e6572206d61792063616c6c20746869732066756e6374696f6e2ea265627a7a7231582046f925e41021178d17fb6770d28206df60eb5dcfb1166013d8b995560e1f065664736f6c63430005110032536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77608060405234801561001057600080fd5b50604051610a72380380610a72833981810160405260a081101561003357600080fd5b508051602082015160408301516060840151608090940151600080546001600160a01b0319166001600160a01b03831617905592939192909190848484848461007e8585858561008d565b505050505050505050506102bc565b6100a7622014808561017060201b6105cc1790919060201c565b6002556100f66100c562201480836101c1602090811b61057317901c565b6100e4670de0b6b3a7640000866101c160201b6105731790919060201c565b61017060201b6105cc1790919060201c565b6001556101118262201480610170602090811b6105cc17901c565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b60006101b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061021a60201b60201c565b90505b92915050565b6000826101d0575060006101bb565b828202828482816101dd57fe5b04146101b85760405162461bcd60e51b8152600401808060200182810382526021815260200180610a516021913960400191505060405180910390fd5b600081836102a65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026b578181015183820152602001610253565b50505050905090810190601f1680156102985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816102b257fe5b0495945050505050565b610786806102cb6000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c80638da5cb5b11610081578063b9f9850a1161005b578063b9f9850a146101d2578063f14039de146101da578063fd2da339146101e2576100b9565b80638da5cb5b14610177578063a385fb961461019b578063b8168816146101a3576100b9565b806315f24053146100be5780632037f3e7146100f95780632191f92a1461012a5780636e71e2d8146101465780638726bb891461016f575b600080fd5b6100e7600480360360608110156100d457600080fd5b50803590602081013590604001356101ea565b60408051918252519081900360200190f35b6101286004803603608081101561010f57600080fd5b5080359060208101359060408101359060600135610201565b005b61013261025c565b604080519115158252519081900360200190f35b6100e76004803603606081101561015c57600080fd5b5080359060208101359060400135610261565b6100e76102b7565b61017f6102bd565b604080516001600160a01b039092168252519081900360200190f35b6100e76102cc565b6100e7600480360360808110156101b957600080fd5b50803590602081013590604081013590606001356102d3565b6100e7610352565b6100e7610358565b6100e761035e565b60006101f7848484610364565b90505b9392505050565b6000546001600160a01b0316331461024a5760405162461bcd60e51b815260040180806020018281038252602681526020018061072c6026913960400191505060405180910390fd5b6102568484848461042d565b50505050565b600181565b600082610270575060006101fa565b6101f761029383610287878763ffffffff6104ce16565b9063ffffffff61053116565b6102ab85670de0b6b3a764000063ffffffff61057316565b9063ffffffff6105cc16565b60015481565b6000546001600160a01b031681565b6220148081565b6000806102ee670de0b6b3a76400008463ffffffff61053116565b905060006102fd878787610364565b9050600061031d670de0b6b3a76400006102ab848663ffffffff61057316565b9050610346670de0b6b3a76400006102ab8361033a8c8c8c610261565b9063ffffffff61057316565b98975050505050505050565b60035481565b60025481565b60045481565b600080610372858585610261565b905060045481116103b8576103b06002546103a4670de0b6b3a76400006102ab6001548661057390919063ffffffff16565b9063ffffffff6104ce16565b9150506101fa565b60006103e36002546103a4670de0b6b3a76400006102ab60015460045461057390919063ffffffff16565b905060006103fc6004548461053190919063ffffffff16565b9050610423826103a4670de0b6b3a76400006102ab6003548661057390919063ffffffff16565b93505050506101fa565b610440846220148063ffffffff6105cc16565b600255610459610293622014808363ffffffff61057316565b60015561046f826220148063ffffffff6105cc16565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b600082820183811015610528576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061052883836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f770081525061060e565b6000826105825750600061052b565b8282028284828161058f57fe5b04146105285760405162461bcd60e51b815260040180806020018281038252602181526020018061070b6021913960400191505060405180910390fd5b600061052883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506106a5565b6000818484111561069d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561066257818101518382015260200161064a565b50505050905090810190601f16801561068f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836106f45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561066257818101518382015260200161064a565b50600083858161070057fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776f6e6c7920746865206f776e6572206d61792063616c6c20746869732066756e6374696f6e2ea265627a7a723158202e4b127b37a8dc3bbcda7c69b711ba801f8ce1922aea2bf8efd29355519ff6e964736f6c63430005110032536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77608060405234801562000010575f80fd5b5060405162000c6238038062000c6283398101604081905262000033916200011b565b818160036200004383826200020d565b5060046200005282826200020d565b5050505050620002d5565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011262000081575f80fd5b81516001600160401b03808211156200009e576200009e6200005d565b604051601f8301601f19908116603f01168101908282118183101715620000c957620000c96200005d565b81604052838152602092508683858801011115620000e5575f80fd5b5f91505b83821015620001085785820183015181830184015290820190620000e9565b5f93810190920192909252949350505050565b5f80604083850312156200012d575f80fd5b82516001600160401b038082111562000144575f80fd5b620001528683870162000071565b9350602085015191508082111562000168575f80fd5b50620001778582860162000071565b9150509250929050565b600181811c908216806200019657607f821691505b602082108103620001b557634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000208575f81815260208120601f850160051c81016020861015620001e35750805b601f850160051c820191505b818110156200020457828155600101620001ef565b5050505b505050565b81516001600160401b038111156200022957620002296200005d565b62000241816200023a845462000181565b84620001bb565b602080601f83116001811462000277575f84156200025f5750858301515b5f19600386901b1c1916600185901b17855562000204565b5f85815260208120601f198616915b82811015620002a75788860151825594840194600190910190840162000286565b5085821015620002c557878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b61097f80620002e35f395ff3fe608060405234801561000f575f80fd5b50600436106100cf575f3560e01c806340c10f191161007d578063a457c2d711610058578063a457c2d7146101a0578063a9059cbb146101b3578063dd62ed3e146101c6575f80fd5b806340c10f191461015b57806370a082311461017057806395d89b4114610198575f80fd5b806323b872dd116100ad57806323b872dd14610126578063313ce567146101395780633950935114610148575f80fd5b806306fdde03146100d3578063095ea7b3146100f157806318160ddd14610114575b5f80fd5b6100db6101fe565b6040516100e891906107da565b60405180910390f35b6101046100ff366004610840565b61028e565b60405190151581526020016100e8565b6002545b6040519081526020016100e8565b610104610134366004610868565b6102a7565b604051601281526020016100e8565b610104610156366004610840565b6102ca565b61016e610169366004610840565b610308565b005b61011861017e3660046108a1565b6001600160a01b03165f9081526020819052604090205490565b6100db610316565b6101046101ae366004610840565b610325565b6101046101c1366004610840565b6103bb565b6101186101d43660046108c1565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b60606003805461020d906108f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610239906108f2565b80156102845780601f1061025b57610100808354040283529160200191610284565b820191905f5260205f20905b81548152906001019060200180831161026757829003601f168201915b5050505050905090565b5f3361029b8185856103c8565b60019150505b92915050565b5f336102b48582856104eb565b6102bf85858561057b565b506001949350505050565b335f8181526001602090815260408083206001600160a01b038716845290915281205490919061029b908290869061030390879061092a565b6103c8565b610312828261071d565b5050565b60606004805461020d906108f2565b335f8181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103ae5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6102bf82868684036103c8565b5f3361029b81858561057b565b6001600160a01b03831661042a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103a5565b6001600160a01b03821661048b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103a5565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811461057557818110156105685760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103a5565b61057584848484036103c8565b50505050565b6001600160a01b0383166105df5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103a5565b6001600160a01b0382166106415760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103a5565b6001600160a01b0383165f90815260208190526040902054818110156106b85760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103a5565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610575565b6001600160a01b0382166107735760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103a5565b8060025f828254610784919061092a565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f6020808352835180828501525f5b81811015610805578581018301518582016040015282016107e9565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461083b575f80fd5b919050565b5f8060408385031215610851575f80fd5b61085a83610825565b946020939093013593505050565b5f805f6060848603121561087a575f80fd5b61088384610825565b925061089160208501610825565b9150604084013590509250925092565b5f602082840312156108b1575f80fd5b6108ba82610825565b9392505050565b5f80604083850312156108d2575f80fd5b6108db83610825565b91506108e960208401610825565b90509250929050565b600181811c9082168061090657607f821691505b60208210810361092457634e487b7160e01b5f52602260045260245ffd5b50919050565b808201808211156102a157634e487b7160e01b5f52601160045260245ffdfea26469706673582212206636ede9469f61b76eaab82fc8d0b8b3d4a97b83b559cd700305c8805b90ece864736f6c63430008150033a2646970667358221220bed7bf70b246d69a8c0cc700f806ce5d3d2ff763185fbed1119f2159f6996dbf64736f6c6343000815003360806040523480156200001157600080fd5b5060405162005dfb38038062005dfb83398181016040526101008110156200003857600080fd5b81516020830151604080850151606086015160808701805193519597949692959194919392820192846401000000008211156200007457600080fd5b9083019060208201858111156200008a57600080fd5b8251640100000000811182820188101715620000a557600080fd5b82525081516020918201929091019080838360005b83811015620000d4578181015183820152602001620000ba565b50505050905090810190601f168015620001025780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200012657600080fd5b9083019060208201858111156200013c57600080fd5b82516401000000008111828201881017156200015757600080fd5b82525081516020918201929091019080838360005b83811015620001865781810151838201526020016200016c565b50505050905090810190601f168015620001b45780820380516001836020036101000a031916815260200191505b506040908152602082015191015160038054610100600160a81b03191633610100021790559092509050620001ef8888888888888862000223565b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055506200090d95505050505050565b6200023e868686868686620002d260201b6200155c1760201c565b601180546001600160a01b0319166001600160a01b038981169190911791829055604080516318160ddd60e01b8152905192909116916318160ddd91600480820192602092909190829003018186803b1580156200029b57600080fd5b505afa158015620002b0573d6000803e3d6000fd5b505050506040513d6020811015620002c757600080fd5b505050505050505050565b60035461010090046001600160a01b03163314620003225760405162461bcd60e51b815260040180806020018281038252602481526020018062005d626024913960400191505060405180910390fd5b600954158015620003335750600a54155b620003705760405162461bcd60e51b815260040180806020018281038252602381526020018062005d866023913960400191505060405180910390fd5b600784905583620003b35760405162461bcd60e51b815260040180806020018281038252603081526020018062005da96030913960400191505060405180910390fd5b6000620003c9876001600160e01b03620004e816565b905080156200041f576040805162461bcd60e51b815260206004820152601a60248201527f73657474696e6720636f6d7074726f6c6c6572206661696c6564000000000000604482015290519081900360640190fd5b620004326001600160e01b036200065016565b600955670de0b6b3a7640000600a5562000455866001600160e01b036200065516565b90508015620004965760405162461bcd60e51b815260040180806020018281038252602281526020018062005dd96022913960400191505060405180910390fd5b8351620004ab9060019060208701906200086b565b508251620004c19060029060208601906200086b565b50506003805460ff90921660ff199283161790556000805490911660011790555050505050565b60035460009061010090046001600160a01b0316331462000522576200051a6001603f6001600160e01b03620007fb16565b90506200064b565b60055460408051623f1ee960e11b815290516001600160a01b0392831692851691627e3dd2916004808301926020929190829003018186803b1580156200056857600080fd5b505afa1580156200057d573d6000803e3d6000fd5b505050506040513d60208110156200059457600080fd5b5051620005e8576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190a160005b9150505b919050565b435b90565b600354600090819061010090046001600160a01b03163314620006925762000689600160426001600160e01b03620007fb16565b9150506200064b565b620006a56001600160e01b036200065016565b60095414620006c55762000689600a60416001600160e01b03620007fb16565b600660009054906101000a90046001600160a01b03169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200071757600080fd5b505afa1580156200072c573d6000803e3d6000fd5b505050506040513d60208110156200074357600080fd5b505162000797576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a1600062000647565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360108111156200082b57fe5b8360508111156200083857fe5b604080519283526020830191909152600082820152519081900360600190a18260108111156200086457fe5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620008ae57805160ff1916838001178555620008de565b82800160010185558215620008de579182015b82811115620008de578251825591602001919060010190620008c1565b50620008ec929150620008f0565b5090565b6200065291905b80821115620008ec5760008155600101620008f7565b615445806200091d6000396000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c80637f1e06be116101bd578063bd6d894d116100f9578063f2b3abbd116100a2578063f851a4401161007c578063f851a44014610b2a578063f8f9da2814610b32578063fca7820b14610b3a578063fe9c44ae14610b5757610341565b8063f2b3abbd14610ac6578063f3fdb15a14610aec578063f5e3c46214610af457610341565b8063db006a75116100d3578063db006a7514610a73578063dd62ed3e14610a90578063e9c714f214610abe57610341565b8063bd6d894d14610a02578063c37f68e214610a0a578063c5ebeaec14610a5657610341565b8063a0712d6811610166578063aa5af0fd11610140578063aa5af0fd14610996578063ae9d70b01461099e578063b2a02ff1146109a6578063b71d1a0c146109dc57610341565b8063a0712d6814610945578063a6afed9514610962578063a9059cbb1461096a57610341565b806395d89b411161019757806395d89b41146107c557806395dd9193146107cd57806399d8c1b4146107f357610341565b80637f1e06be1461077a578063852a12e3146107a05780638f840ddd146107bd57610341565b8063313ce5671161028c5780635fe3b567116102355780636c540baf1161020f5780636c540baf1461073c5780636f307dc31461074457806370a082311461074c57806373acee981461077257610341565b80635fe3b5671461070f578063601a0bf1146107175780636752e7021461073457610341565b80633e941010116102665780633e941010146106c45780634576b5db146106e157806347bd37181461070757610341565b8063313ce567146106785780633af9e669146106965780633b1d21a2146106bc57610341565b8063182df0f5116102ee57806323b872dd116102c857806323b872dd146105f25780632608f81814610628578063267822471461065457610341565b8063182df0f5146104685780631a31d465146104705780631be19560146105cc57610341565b8063173b99041161031f578063173b99041461043257806317bfdfbc1461043a57806318160ddd1461046057610341565b806306fdde0314610346578063095ea7b3146103c35780630e75270214610403575b600080fd5b61034e610b5f565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610388578181015183820152602001610370565b50505050905090810190601f1680156103b55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ef600480360360408110156103d957600080fd5b506001600160a01b038135169060200135610bec565b604080519115158252519081900360200190f35b6104206004803603602081101561041957600080fd5b5035610c59565b60408051918252519081900360200190f35b610420610c6f565b6104206004803603602081101561045057600080fd5b50356001600160a01b0316610c75565b610420610d35565b610420610d3b565b6105ca600480360360e081101561048657600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156104c957600080fd5b8201836020820111156104db57600080fd5b803590602001918460018302840111640100000000831117156104fd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561055057600080fd5b82018360208201111561056257600080fd5b8035906020019184600183028401116401000000008311171561058457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff169150610d9e9050565b005b6105ca600480360360208110156105e257600080fd5b50356001600160a01b0316610e3d565b6103ef6004803603606081101561060857600080fd5b506001600160a01b03813581169160208101359091169060400135610f79565b6104206004803603604081101561063e57600080fd5b506001600160a01b038135169060200135610feb565b61065c611001565b604080516001600160a01b039092168252519081900360200190f35b610680611010565b6040805160ff9092168252519081900360200190f35b610420600480360360208110156106ac57600080fd5b50356001600160a01b0316611019565b6104206110cf565b610420600480360360208110156106da57600080fd5b50356110de565b610420600480360360208110156106f757600080fd5b50356001600160a01b03166110e9565b61042061123e565b61065c611244565b6104206004803603602081101561072d57600080fd5b5035611253565b6104206112ee565b6104206112f9565b61065c6112ff565b6104206004803603602081101561076257600080fd5b50356001600160a01b031661130e565b610420611329565b6105ca6004803603602081101561079057600080fd5b50356001600160a01b03166113df565b610420600480360360208110156107b657600080fd5b5035611496565b6104206114a1565b61034e6114a7565b610420600480360360208110156107e357600080fd5b50356001600160a01b03166114ff565b6105ca600480360360c081101561080957600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561084457600080fd5b82018360208201111561085657600080fd5b8035906020019184600183028401116401000000008311171561087857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156108cb57600080fd5b8201836020820111156108dd57600080fd5b803590602001918460018302840111640100000000831117156108ff57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff16915061155c9050565b6104206004803603602081101561095b57600080fd5b5035611743565b61042061174f565b6103ef6004803603604081101561098057600080fd5b506001600160a01b038135169060200135611aa7565b610420611b18565b610420611b1e565b610420600480360360608110156109bc57600080fd5b506001600160a01b03813581169160208101359091169060400135611bbd565b610420600480360360208110156109f257600080fd5b50356001600160a01b0316611c2e565b610420611cba565b610a3060048036036020811015610a2057600080fd5b50356001600160a01b0316611d76565b604080519485526020850193909352838301919091526060830152519081900360800190f35b61042060048036036020811015610a6c57600080fd5b5035611e0b565b61042060048036036020811015610a8957600080fd5b5035611e16565b61042060048036036040811015610aa657600080fd5b506001600160a01b0381358116916020013516611e21565b610420611e4c565b61042060048036036020811015610adc57600080fd5b50356001600160a01b0316611f5c565b61065c611f96565b61042060048036036060811015610b0a57600080fd5b506001600160a01b03813581169160208101359160409091013516611fa5565b61065c611fbd565b610420611fd1565b61042060048036036020811015610b5057600080fd5b5035612035565b6103ef6120b3565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be45780601f10610bb957610100808354040283529160200191610be4565b820191906000526020600020905b815481529060010190602001808311610bc757829003601f168201915b505050505081565b336000818152600f602090815260408083206001600160a01b03871680855290835281842086905581518681529151939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a360019150505b92915050565b600080610c65836120b8565b509150505b919050565b60085481565b6000805460ff16610cba576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155610ccc61174f565b14610d17576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b610d20826114ff565b90505b6000805460ff19166001179055919050565b600d5481565b6000806000610d48612161565b90925090506000826003811115610d5b57fe5b14610d975760405162461bcd60e51b815260040180806020018281038252603581526020018061535c6035913960400191505060405180910390fd5b9150505b90565b610dac86868686868661155c565b601180546001600160a01b0319166001600160a01b038981169190911791829055604080516318160ddd60e01b8152905192909116916318160ddd91600480820192602092909190829003018186803b158015610e0857600080fd5b505afa158015610e1c573d6000803e3d6000fd5b505050506040513d6020811015610e3257600080fd5b505050505050505050565b6011546001600160a01b0382811691161415610e8a5760405162461bcd60e51b815260040180806020018281038252603281526020018061518b6032913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b158015610ed457600080fd5b505afa158015610ee8573d6000803e3d6000fd5b505050506040513d6020811015610efe57600080fd5b50516003546040805163a9059cbb60e01b81526101009092046001600160a01b03908116600484015260248301849052905192935084169163a9059cbb9160448082019260009290919082900301818387803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b505050505050565b6000805460ff16610fbe576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155610fd433868686612210565b1490506000805460ff191660011790559392505050565b600080610ff8848461249c565b50949350505050565b6004546001600160a01b031681565b60035460ff1681565b6000611023614f9e565b6040518060200160405280611036611cba565b90526001600160a01b0384166000908152600e6020526040812054919250908190611062908490612547565b9092509050600082600381111561107557fe5b146110c7576040805162461bcd60e51b815260206004820152601f60248201527f62616c616e636520636f756c64206e6f742062652063616c63756c6174656400604482015290519081900360640190fd5b949350505050565b60006110d961259b565b905090565b6000610c538261261b565b60035460009061010090046001600160a01b031633146111165761110f6001603f6126af565b9050610c6a565b60055460408051623f1ee960e11b815290516001600160a01b0392831692851691627e3dd2916004808301926020929190829003018186803b15801561115b57600080fd5b505afa15801561116f573d6000803e3d6000fd5b505050506040513d602081101561118557600080fd5b50516111d8576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190a160005b9392505050565b600b5481565b6005546001600160a01b031681565b6000805460ff16611298576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff191681556112aa61174f565b905080156112d0576112c88160108111156112c157fe5b60306126af565b915050610d23565b6112d983612715565b9150506000805460ff19166001179055919050565b666379da05b6000081565b60095481565b6011546001600160a01b031681565b6001600160a01b03166000908152600e602052604090205490565b6000805460ff1661136e576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561138061174f565b146113cb576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b50600b546000805460ff1916600117905590565b60035461010090046001600160a01b0316331461142d5760405162461bcd60e51b815260040180806020018281038252602d8152602001806151ed602d913960400191505060405180910390fd5b601154604080516317066a5760e21b81526001600160a01b03848116600483015291519190921691635c19a95c91602480830192600092919082900301818387803b15801561147b57600080fd5b505af115801561148f573d6000803e3d6000fd5b5050505050565b6000610c5382612848565b600c5481565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610be45780601f10610bb957610100808354040283529160200191610be4565b600080600061150d846128c9565b9092509050600082600381111561152057fe5b146112375760405162461bcd60e51b81526004018080602001828103825260378152602001806152676037913960400191505060405180910390fd5b60035461010090046001600160a01b031633146115aa5760405162461bcd60e51b81526004018080602001828103825260248152602001806151446024913960400191505060405180910390fd5b6009541580156115ba5750600a54155b6115f55760405162461bcd60e51b81526004018080602001828103825260238152602001806151686023913960400191505060405180910390fd5b6007849055836116365760405162461bcd60e51b81526004018080602001828103825260308152602001806151bd6030913960400191505060405180910390fd5b6000611641876110e9565b90508015611696576040805162461bcd60e51b815260206004820152601a60248201527f73657474696e6720636f6d7074726f6c6c6572206661696c6564000000000000604482015290519081900360640190fd5b61169e61297d565b600955670de0b6b3a7640000600a556116b686612981565b905080156116f55760405162461bcd60e51b815260040180806020018281038252602281526020018061521a6022913960400191505060405180910390fd5b8351611708906001906020870190614fb1565b50825161171c906002906020860190614fb1565b50506003805460ff90921660ff199283161790556000805490911660011790555050505050565b600080610c6583612af6565b60008061175a61297d565b6009549091508082141561177357600092505050610d9b565b600061177d61259b565b600b54600c54600a54600654604080516315f2405360e01b815260048101879052602481018690526044810185905290519596509394929391926000926001600160a01b03909216916315f24053916064808301926020929190829003018186803b1580156117eb57600080fd5b505afa1580156117ff573d6000803e3d6000fd5b505050506040513d602081101561181557600080fd5b5051905065048c27395000811115611874576040805162461bcd60e51b815260206004820152601c60248201527f626f72726f772072617465206973206162737572646c79206869676800000000604482015290519081900360640190fd5b6000806118818989612b77565b9092509050600082600381111561189457fe5b146118e6576040805162461bcd60e51b815260206004820152601f60248201527f636f756c64206e6f742063616c63756c61746520626c6f636b2064656c746100604482015290519081900360640190fd5b6118ee614f9e565b60008060008061190c60405180602001604052808a81525087612b9a565b9097509450600087600381111561191f57fe5b146119515761193c6009600689600381111561193757fe5b612c02565b9e505050505050505050505050505050610d9b565b61195b858c612547565b9097509350600087600381111561196e57fe5b146119865761193c6009600189600381111561193757fe5b611990848c612c68565b909750925060008760038111156119a357fe5b146119bb5761193c6009600489600381111561193757fe5b6119d66040518060200160405280600854815250858c612c8e565b909750915060008760038111156119e957fe5b14611a015761193c6009600589600381111561193757fe5b611a0c858a8b612c8e565b90975090506000876003811115611a1f57fe5b14611a375761193c6009600389600381111561193757fe5b60098e9055600a819055600b839055600c829055604080518d8152602081018690528082018390526060810185905290517f4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc049181900360800190a160009e50505050505050505050505050505090565b6000805460ff16611aec576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155611b0233338686612210565b1490506000805460ff1916600117905592915050565b600a5481565b6006546000906001600160a01b031663b8168816611b3a61259b565b600b54600c546008546040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060206040518083038186803b158015611b8c57600080fd5b505afa158015611ba0573d6000803e3d6000fd5b505050506040513d6020811015611bb657600080fd5b5051905090565b6000805460ff16611c02576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19169055611c1833858585612cea565b90506000805460ff191660011790559392505050565b60035460009061010090046001600160a01b03163314611c545761110f600160456126af565b600480546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000611237565b6000805460ff16611cff576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155611d1161174f565b14611d5c576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b611d64610d3b565b90506000805460ff1916600117905590565b6001600160a01b0381166000908152600e6020526040812054819081908190818080611da1896128c9565b935090506000816003811115611db357fe5b14611dd15760095b975060009650869550859450611e049350505050565b611dd9612161565b925090506000816003811115611deb57fe5b14611df7576009611dbb565b5060009650919450925090505b9193509193565b6000610c53826130c4565b6000610c5382613143565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b6004546000906001600160a01b031633141580611e67575033155b15611e7f57611e78600160006126af565b9050610d9b565b60038054600480546001600160a01b0381811661010081810274ffffffffffffffffffffffffffffffffffffffff0019871617968790556001600160a01b031990931690935560408051948390048216808652929095041660208401528351909391927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a1600454604080516001600160a01b038085168252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a160009250505090565b600080611f6761174f565b90508015611f8d57611f85816010811115611f7e57fe5b60406126af565b915050610c6a565b61123783612981565b6006546001600160a01b031681565b600080611fb38585856131bd565b5095945050505050565b60035461010090046001600160a01b031681565b6006546000906001600160a01b03166315f24053611fed61259b565b600b54600c546040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015611b8c57600080fd5b6000805460ff1661207a576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561208c61174f565b905080156120aa576112c88160108111156120a357fe5b60466126af565b6112d9836132ef565b600181565b60008054819060ff166120ff576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561211161174f565b9050801561213c5761212f81601081111561212857fe5b60366126af565b92506000915061214d9050565b612147333386613397565b92509250505b6000805460ff191660011790559092909150565b600d5460009081908061217c5750506007546000915061220c565b600061218661259b565b90506000612192614f9e565b60006121a384600b54600c546136e5565b9350905060008160038111156121b557fe5b146121ca5795506000945061220c9350505050565b6121d48386613723565b9250905060008160038111156121e657fe5b146121fb5795506000945061220c9350505050565b505160009550935061220c92505050565b9091565b600554604080516317b9b84b60e31b81523060048201526001600160a01b03868116602483015285811660448301526064820185905291516000938493169163bdcdc25891608480830192602092919082900301818787803b15801561227557600080fd5b505af1158015612289573d6000803e3d6000fd5b505050506040513d602081101561229f57600080fd5b5051905080156122be576122b66003604a83612c02565b9150506110c7565b836001600160a01b0316856001600160a01b031614156122e4576122b66002604b6126af565b60006001600160a01b038781169087161415612303575060001961232b565b506001600160a01b038086166000908152600f60209081526040808320938a16835292905220545b60008060008061233b8589612b77565b9094509250600084600381111561234e57fe5b1461236c5761235f6009604b6126af565b96505050505050506110c7565b6001600160a01b038a166000908152600e602052604090205461238f9089612b77565b909450915060008460038111156123a257fe5b146123b35761235f6009604c6126af565b6001600160a01b0389166000908152600e60205260409020546123d69089612c68565b909450905060008460038111156123e957fe5b146123fa5761235f6009604d6126af565b6001600160a01b03808b166000908152600e6020526040808220859055918b168152208190556000198514612452576001600160a01b03808b166000908152600f60209081526040808320938f168352929052208390555b886001600160a01b03168a6001600160a01b03166000805160206152d88339815191528a6040518082815260200191505060405180910390a35060009a9950505050505050505050565b60008054819060ff166124e3576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff191681556124f561174f565b905080156125205761251381601081111561250c57fe5b60356126af565b9250600091506125319050565b61252b338686613397565b92509250505b6000805460ff1916600117905590939092509050565b6000806000612554614f9e565b61255e8686612b9a565b9092509050600082600381111561257157fe5b146125825750915060009050612594565b600061258d826137d3565b9350935050505b9250929050565b601154604080516370a0823160e01b815230600482015290516000926001600160a01b03169182916370a0823191602480820192602092909190829003018186803b1580156125e957600080fd5b505afa1580156125fd573d6000803e3d6000fd5b505050506040513d602081101561261357600080fd5b505191505090565b6000805460ff16612660576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561267261174f565b90508015612690576112c881601081111561268957fe5b604e6126af565b612699836137e2565b509150506000805460ff19166001179055919050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360108111156126de57fe5b8360508111156126ea57fe5b604080519283526020830191909152600082820152519081900360600190a182601081111561123757fe5b600354600090819061010090046001600160a01b0316331461273d57611f85600160316126af565b61274561297d565b6009541461275957611f85600a60336126af565b8261276261259b565b101561277457611f85600e60326126af565b600c5483111561278a57611f85600260346126af565b50600c54828103908111156127d05760405162461bcd60e51b81526004018080602001828103825260248152602001806153ed6024913960400191505060405180910390fd5b600c8190556003546127f09061010090046001600160a01b0316846138ca565b600354604080516101009092046001600160a01b0316825260208201859052818101839052517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e916060908290030190a16000611237565b6000805460ff1661288d576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561289f61174f565b905080156128bd576112c88160108111156128b657fe5b60276126af565b6112d9336000856139c1565b6001600160a01b03811660009081526010602052604081208054829182918291829161290057506000945084935061297892505050565b6129108160000154600a54613e88565b9094509250600084600381111561292357fe5b14612938575091935060009250612978915050565b612946838260010154613ec7565b9094509150600084600381111561295957fe5b1461296e575091935060009250612978915050565b5060009450925050505b915091565b4390565b600354600090819061010090046001600160a01b031633146129a957611f85600160426126af565b6129b161297d565b600954146129c557611f85600a60416126af565b600660009054906101000a90046001600160a01b03169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1657600080fd5b505afa158015612a2a573d6000803e3d6000fd5b505050506040513d6020811015612a4057600080fd5b5051612a93576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000611237565b60008054819060ff16612b3d576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155612b4f61174f565b90508015612b6d5761212f816010811115612b6657fe5b601e6126af565b6121473385613ef2565b600080838311612b8e575060009050818303612594565b50600390506000612594565b6000612ba4614f9e565b600080612bb5866000015186613e88565b90925090506000826003811115612bc857fe5b14612be757506040805160208101909152600081529092509050612594565b60408051602081019091529081526000969095509350505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846010811115612c3157fe5b846050811115612c3d57fe5b604080519283526020830191909152818101859052519081900360600190a18360108111156110c757fe5b600080838301848110612c8057600092509050612594565b506002915060009050612594565b6000806000612c9b614f9e565b612ca58787612b9a565b90925090506000826003811115612cb857fe5b14612cc95750915060009050612ce2565b612cdb612cd5826137d3565b86612c68565b9350935050505b935093915050565b6005546040805163d02f735160e01b81523060048201526001600160a01b038781166024830152868116604483015285811660648301526084820185905291516000938493169163d02f73519160a480830192602092919082900301818787803b158015612d5757600080fd5b505af1158015612d6b573d6000803e3d6000fd5b505050506040513d6020811015612d8157600080fd5b505190508015612d98576122b66003601b83612c02565b846001600160a01b0316846001600160a01b03161415612dbe576122b66006601c6126af565b612dc661502f565b6001600160a01b0385166000908152600e6020526040902054612de99085612b77565b6020830181905282826003811115612dfd57fe5b6003811115612e0857fe5b9052506000905081516003811115612e1c57fe5b14612e4157612e386009601a8360000151600381111561193757fe5b925050506110c7565b612e60846040518060200160405280666379da05b600008152506142c2565b60808201819052612e729085906142ea565b6060820152612e7f612161565b60c0830181905282826003811115612e9357fe5b6003811115612e9e57fe5b9052506000905081516003811115612eb257fe5b14612f04576040805162461bcd60e51b815260206004820152601860248201527f65786368616e67652072617465206d617468206572726f720000000000000000604482015290519081900360640190fd5b612f2460405180602001604052808360c00151815250826080015161432c565b60a08201819052600c54612f379161434b565b60e0820152600d546080820151612f4e91906142ea565b6101008201526001600160a01b0386166000908152600e60205260409020546060820151612f7c9190612c68565b6040830181905282826003811115612f9057fe5b6003811115612f9b57fe5b9052506000905081516003811115612faf57fe5b14612fcb57612e38600960198360000151600381111561193757fe5b60e0810151600c55610100810151600d556020808201516001600160a01b038088166000818152600e855260408082209490945583860151928b168082529084902092909255606085015183519081529251919390926000805160206152d8833981519152929081900390910190a36080810151604080519182525130916001600160a01b038816916000805160206152d88339815191529181900360200190a360a081015160e082015160408051308152602081019390935282810191909152517fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc59181900360600190a16000979650505050505050565b6000805460ff16613109576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561311b61174f565b90508015613139576112c881601081111561313257fe5b60086126af565b6112d93384614381565b6000805460ff16613188576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561319a61174f565b905080156131b1576112c88160108111156128b657fe5b6112d9338460006139c1565b60008054819060ff16613204576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561321661174f565b905080156132415761323481601081111561322d57fe5b600f6126af565b9250600091506132d89050565b836001600160a01b031663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561327c57600080fd5b505af1158015613290573d6000803e3d6000fd5b505050506040513d60208110156132a657600080fd5b5051905080156132c6576132348160108111156132bf57fe5b60106126af565b6132d233878787614615565b92509250505b6000805460ff191660011790559094909350915050565b60035460009061010090046001600160a01b031633146133155761110f600160476126af565b61331d61297d565b600954146133315761110f600a60486126af565b670de0b6b3a764000082111561334d5761110f600260496126af565b6008805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000611237565b60055460408051631200453160e11b81523060048201526001600160a01b0386811660248301528581166044830152606482018590529151600093849384939116916324008a629160848082019260209290919082900301818787803b15801561340057600080fd5b505af1158015613414573d6000803e3d6000fd5b505050506040513d602081101561342a57600080fd5b50519050801561344e576134416003603883612c02565b925060009150612ce29050565b61345661297d565b6009541461346a57613441600a60396126af565b61347261507c565b6001600160a01b038616600090815260106020526040902060010154606082015261349c866128c9565b60808301819052602083018260038111156134b357fe5b60038111156134be57fe5b90525060009050816020015160038111156134d557fe5b146134ff576134f1600960378360200151600381111561193757fe5b935060009250612ce2915050565b6000198514156135185760808101516040820152613520565b604081018590525b61352e878260400151614b10565b60e08201819052608082015161354391612b77565b60a083018190526020830182600381111561355a57fe5b600381111561356557fe5b905250600090508160200151600381111561357c57fe5b146135b85760405162461bcd60e51b815260040180806020018281038252603a81526020018061529e603a913960400191505060405180910390fd5b6135c8600b548260e00151612b77565b60c08301819052602083018260038111156135df57fe5b60038111156135ea57fe5b905250600090508160200151600381111561360157fe5b1461363d5760405162461bcd60e51b81526004018080602001828103825260318152602001806152f86031913960400191505060405180910390fd5b60a080820180516001600160a01b03808a16600081815260106020908152604091829020948555600a5460019095019490945560c0870151600b81905560e088015195518251948f16855294840192909252828101949094526060820192909252608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1929181900390910190a160e00151600097909650945050505050565b6000806000806136f58787612c68565b9092509050600082600381111561370857fe5b146137195750915060009050612ce2565b612cdb8186612b77565b600061372d614f9e565b60008061374286670de0b6b3a7640000613e88565b9092509050600082600381111561375557fe5b1461377457506040805160208101909152600081529092509050612594565b6000806137818388613ec7565b9092509050600082600381111561379457fe5b146137b657506040805160208101909152600081529094509250612594915050565b604080516020810190915290815260009890975095505050505050565b51670de0b6b3a7640000900490565b6000806000806137f061297d565b6009541461380f57613804600a604f6126af565b935091506129789050565b6138193386614b10565b905080600c54019150600c54821015613879576040805162461bcd60e51b815260206004820181905260248201527f61646420726573657276657320756e6578706563746564206f766572666c6f77604482015290519081900360640190fd5b600c829055604080513381526020810183905280820184905290517fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc59181900360600190a160009350915050915091565b6011546040805163a9059cbb60e01b81526001600160a01b0385811660048301526024820185905291519190921691829163a9059cbb9160448082019260009290919082900301818387803b15801561392257600080fd5b505af1158015613936573d6000803e3d6000fd5b5050505060003d60008114613952576020811461395c57600080fd5b6000199150613968565b60206000803e60005191505b50806139bb576040805162461bcd60e51b815260206004820152601960248201527f544f4b454e5f5452414e534645525f4f55545f4641494c454400000000000000604482015290519081900360640190fd5b50505050565b60008215806139ce575081155b613a095760405162461bcd60e51b81526004018080602001828103825260348152602001806153b96034913960400191505060405180910390fd5b613a116150c2565b613a19612161565b6040830181905260208301826003811115613a3057fe5b6003811115613a3b57fe5b9052506000905081602001516003811115613a5257fe5b14613a7657613a6e6009602b8360200151600381111561193757fe5b915050611237565b8315613af7576060810184905260408051602081018252908201518152613a9d9085612547565b6080830181905260208301826003811115613ab457fe5b6003811115613abf57fe5b9052506000905081602001516003811115613ad657fe5b14613af257613a6e600960298360200151600381111561193757fe5b613b70565b613b138360405180602001604052808460400151815250614d5a565b6060830181905260208301826003811115613b2a57fe5b6003811115613b3557fe5b9052506000905081602001516003811115613b4c57fe5b14613b6857613a6e6009602a8360200151600381111561193757fe5b608081018390525b60055460608201516040805163eabe7d9160e01b81523060048201526001600160a01b03898116602483015260448201939093529051600093929092169163eabe7d919160648082019260209290919082900301818787803b158015613bd557600080fd5b505af1158015613be9573d6000803e3d6000fd5b505050506040513d6020811015613bff57600080fd5b505190508015613c1f57613c166003602883612c02565b92505050611237565b613c2761297d565b60095414613c3b57613c16600a602c6126af565b613c4b600d548360600151612b77565b60a0840181905260208401826003811115613c6257fe5b6003811115613c6d57fe5b9052506000905082602001516003811115613c8457fe5b14613ca057613c166009602e8460200151600381111561193757fe5b6001600160a01b0386166000908152600e60205260409020546060830151613cc89190612b77565b60c0840181905260208401826003811115613cdf57fe5b6003811115613cea57fe5b9052506000905082602001516003811115613d0157fe5b14613d1d57613c166009602d8460200151600381111561193757fe5b8160800151613d2a61259b565b1015613d3c57613c16600e602f6126af565b613d4a8683608001516138ca565b60a0820151600d5560c08201516001600160a01b0387166000818152600e60209081526040918290209390935560608501518151908152905130936000805160206152d8833981519152928290030190a36080820151606080840151604080516001600160a01b038b168152602081019490945283810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9299281900390910190a160055460808301516060840151604080516351dff98960e01b81523060048201526001600160a01b038b81166024830152604482019490945260648101929092525191909216916351dff98991608480830192600092919082900301818387803b158015613e5d57600080fd5b505af1158015613e71573d6000803e3d6000fd5b5060009250613e7e915050565b9695505050505050565b60008083613e9b57506000905080612594565b83830283858281613ea857fe5b0414613ebc57506002915060009050612594565b600092509050612594565b60008082613edb5750600190506000612594565b6000838581613ee657fe5b04915091509250929050565b60055460408051634ef4c3e160e01b81523060048201526001600160a01b03858116602483015260448201859052915160009384938493911691634ef4c3e19160648082019260209290919082900301818787803b158015613f5357600080fd5b505af1158015613f67573d6000803e3d6000fd5b505050506040513d6020811015613f7d57600080fd5b505190508015613fa157613f946003601f83612c02565b9250600091506125949050565b613fa961297d565b60095414613fbd57613f94600a60226126af565b613fc56150c2565b613fcd612161565b6040830181905260208301826003811115613fe457fe5b6003811115613fef57fe5b905250600090508160200151600381111561400657fe5b1461403057614022600960218360200151600381111561193757fe5b935060009250612594915050565b61403a8686614b10565b60c082018190526040805160208101825290830151815261405b9190614d5a565b606083018190526020830182600381111561407257fe5b600381111561407d57fe5b905250600090508160200151600381111561409457fe5b146140e6576040805162461bcd60e51b815260206004820181905260248201527f4d494e545f45584348414e47455f43414c43554c4154494f4e5f4641494c4544604482015290519081900360640190fd5b6140f6600d548260600151612c68565b608083018190526020830182600381111561410d57fe5b600381111561411857fe5b905250600090508160200151600381111561412f57fe5b1461416b5760405162461bcd60e51b81526004018080602001828103825260288152602001806153916028913960400191505060405180910390fd5b6001600160a01b0386166000908152600e602052604090205460608201516141939190612c68565b60a08301819052602083018260038111156141aa57fe5b60038111156141b557fe5b90525060009050816020015160038111156141cc57fe5b146142085760405162461bcd60e51b815260040180806020018281038252602b81526020018061523c602b913960400191505060405180910390fd5b6080810151600d5560a08101516001600160a01b0387166000818152600e60209081526040918290209390935560c084015160608086015183519485529484019190915282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160a01b0388169130916000805160206152d88339815191529181900360200190a360c001516000969095509350505050565b6000670de0b6b3a76400006142db848460000151614d71565b816142e257fe5b049392505050565b600061123783836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f770000000000000000000000815250614db3565b6000614336614f9e565b6143408484614e4a565b90506110c7816137d3565b60006112378383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b815250614e74565b6005546040805163368f515360e21b81523060048201526001600160a01b0385811660248301526044820185905291516000938493169163da3d454c91606480830192602092919082900301818787803b1580156143de57600080fd5b505af11580156143f2573d6000803e3d6000fd5b505050506040513d602081101561440857600080fd5b5051905080156144275761441f6003600e83612c02565b915050610c53565b61442f61297d565b600954146144425761441f600a806126af565b8261444b61259b565b101561445d5761441f600e60096126af565b614465615100565b61446e856128c9565b602083018190528282600381111561448257fe5b600381111561448d57fe5b90525060009050815160038111156144a157fe5b146144c6576144bd600960078360000151600381111561193757fe5b92505050610c53565b6144d4816020015185612c68565b60408301819052828260038111156144e857fe5b60038111156144f357fe5b905250600090508151600381111561450757fe5b14614523576144bd6009600c8360000151600381111561193757fe5b61452f600b5485612c68565b606083018190528282600381111561454357fe5b600381111561454e57fe5b905250600090508151600381111561456257fe5b1461457e576144bd6009600b8360000151600381111561193757fe5b61458885856138ca565b604080820180516001600160a01b03881660008181526010602090815290859020928355600a54600190930192909255606080860151600b81905593518551928352928201899052818501929092529081019190915290517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab809181900360800190a1600095945050505050565b60055460408051632fe3f38f60e11b81523060048201526001600160a01b0384811660248301528781166044830152868116606483015260848201869052915160009384938493911691635fc7e71e9160a48082019260209290919082900301818787803b15801561468657600080fd5b505af115801561469a573d6000803e3d6000fd5b505050506040513d60208110156146b057600080fd5b5051905080156146d4576146c76003601283612c02565b925060009150614b079050565b6146dc61297d565b600954146146f0576146c7600a60166126af565b6146f861297d565b846001600160a01b0316636c540baf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561473157600080fd5b505afa158015614745573d6000803e3d6000fd5b505050506040513d602081101561475b57600080fd5b50511461476e576146c7600a60116126af565b866001600160a01b0316866001600160a01b03161415614794576146c7600660176126af565b846147a5576146c7600760156126af565b6000198514156147bb576146c7600760146126af565b6000806147c9898989613397565b909250905081156147f9576147ea8260108111156147e357fe5b60186126af565b945060009350614b0792505050565b6005546040805163c488847b60e01b81523060048201526001600160a01b038981166024830152604482018590528251600094859492169263c488847b926064808301939192829003018186803b15801561485357600080fd5b505afa158015614867573d6000803e3d6000fd5b505050506040513d604081101561487d57600080fd5b508051602090910151909250905081156148c85760405162461bcd60e51b81526004018080602001828103825260338152602001806153296033913960400191505060405180910390fd5b80886001600160a01b03166370a082318c6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561491f57600080fd5b505afa158015614933573d6000803e3d6000fd5b505050506040513d602081101561494957600080fd5b5051101561499e576040805162461bcd60e51b815260206004820152601860248201527f4c49515549444154455f5345495a455f544f4f5f4d5543480000000000000000604482015290519081900360640190fd5b60006001600160a01b0389163014156149c4576149bd308d8d85612cea565b9050614a4e565b6040805163b2a02ff160e01b81526001600160a01b038e811660048301528d81166024830152604482018590529151918b169163b2a02ff1916064808201926020929091908290030181600087803b158015614a1f57600080fd5b505af1158015614a33573d6000803e3d6000fd5b505050506040513d6020811015614a4957600080fd5b505190505b8015614aa1576040805162461bcd60e51b815260206004820152601460248201527f746f6b656e207365697a757265206661696c6564000000000000000000000000604482015290519081900360640190fd5b604080516001600160a01b03808f168252808e1660208301528183018790528b1660608201526080810184905290517f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb529181900360a00190a16000975092955050505050505b94509492505050565b601154604080516370a0823160e01b815230600482015290516000926001600160a01b031691839183916370a08231916024808301926020929190829003018186803b158015614b5f57600080fd5b505afa158015614b73573d6000803e3d6000fd5b505050506040513d6020811015614b8957600080fd5b5051604080516323b872dd60e01b81526001600160a01b038881166004830152306024830152604482018890529151929350908416916323b872dd9160648082019260009290919082900301818387803b158015614be657600080fd5b505af1158015614bfa573d6000803e3d6000fd5b5050505060003d60008114614c165760208114614c2057600080fd5b6000199150614c2c565b60206000803e60005191505b5080614c7f576040805162461bcd60e51b815260206004820152601860248201527f544f4b454e5f5452414e534645525f494e5f4641494c45440000000000000000604482015290519081900360640190fd5b601154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015614cca57600080fd5b505afa158015614cde573d6000803e3d6000fd5b505050506040513d6020811015614cf457600080fd5b5051905082811015614d4d576040805162461bcd60e51b815260206004820152601a60248201527f544f4b454e5f5452414e534645525f494e5f4f564552464c4f57000000000000604482015290519081900360640190fd5b9190910395945050505050565b6000806000614d67614f9e565b61255e8686614ec9565b600061123783836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250614f28565b60008184841115614e425760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614e07578181015183820152602001614def565b50505050905090810190601f168015614e345780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b614e52614f9e565b6040518060200160405280614e6b856000015185614d71565b90529392505050565b60008383018285821015610ff85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614e07578181015183820152602001614def565b6000614ed3614f9e565b600080614ee8670de0b6b3a764000087613e88565b90925090506000826003811115614efb57fe5b14614f1a57506040805160208101909152600081529092509050612594565b61258d818660000151613723565b6000831580614f35575082155b15614f4257506000611237565b83830283858281614f4f57fe5b04148390610ff85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614e07578181015183820152602001614def565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ff257805160ff191683800117855561501f565b8280016001018555821561501f579182015b8281111561501f578251825591602001919060010190615004565b5061502b929150615129565b5090565b604080516101208101909152806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160e0810190915280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b610d9b91905b8082111561502b576000815560010161512f56fe6f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e63654345726332303a3a7377656570546f6b656e3a2063616e206e6f7420737765657020756e6465726c79696e6720746f6b656e696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e6f6e6c79207468652061646d696e206d6179207365742074686520636f6d702d6c696b652064656c656761746573657474696e6720696e7465726573742072617465206d6f64656c206661696c65644d494e545f4e45575f4143434f554e545f42414c414e43455f43414c43554c4154494f4e5f4641494c4544626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e636553746f726564496e7465726e616c206661696c656452455041595f424f52524f575f4e45575f4143434f554e545f424f52524f575f42414c414e43455f43414c43554c4154494f4e5f4641494c4544ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef52455041595f424f52524f575f4e45575f544f54414c5f42414c414e43455f43414c43554c4154494f4e5f4641494c45444c49515549444154455f434f4d5054524f4c4c45525f43414c43554c4154455f414d4f554e545f5345495a455f4641494c454465786368616e67655261746553746f7265643a2065786368616e67655261746553746f726564496e7465726e616c206661696c65644d494e545f4e45575f544f54414c5f535550504c595f43414c43554c4154494f4e5f4641494c45446f6e65206f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e206d757374206265207a65726f72656475636520726573657276657320756e657870656374656420756e646572666c6f77a265627a7a72315820952b149004d6331a6bdeb8cd0645bbfd988cf14277209b41ab9c7444e28c7e8364736f6c634300051100326f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e6365696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e73657474696e6720696e7465726573742072617465206d6f64656c206661696c6564608060405234801561001057600080fd5b506105ae806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806309a8acb01461005c578063127ffda01461008a5780635e9a523c146100b657806366331bba146100ee578063fc57d4df1461010a575b600080fd5b6100886004803603604081101561007257600080fd5b506001600160a01b038135169060200135610130565b005b610088600480360360408110156100a057600080fd5b506001600160a01b0381351690602001356101a8565b6100dc600480360360208110156100cc57600080fd5b50356001600160a01b031661028a565b60408051918252519081900360200190f35b6100f66102a9565b604080519115158252519081900360200190f35b6100dc6004803603602081101561012057600080fd5b50356001600160a01b03166102ae565b6001600160a01b038216600081815260208181526040918290205482519384529083015281810183905260608201839052517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a16001600160a01b03909116600090815260208190526040902055565b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156101e357600080fd5b505afa1580156101f7573d6000803e3d6000fd5b505050506040513d602081101561020d57600080fd5b50516001600160a01b038116600081815260208181526040918290205482519384529083015281810185905260608201859052519192507fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae7919081900360800190a16001600160a01b031660009081526020819052604090205550565b6001600160a01b0381166000908152602081905260409020545b919050565b600181565b60006103f5826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156102ec57600080fd5b505afa158015610300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561032957600080fd5b810190808051604051939291908464010000000082111561034957600080fd5b90830190602082018581111561035e57600080fd5b825164010000000081118282018810171561037857600080fd5b82525081516020918201929091019080838360005b838110156103a557818101518382015260200161038d565b50505050905090810190601f1680156103d25780820380516001836020036101000a031916815260200191505b506040818101905260048152630c68aa8960e31b60208201529250610492915050565b156104095750670de0b6b3a76400006102a4565b600080836001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561044557600080fd5b505afa158015610459573d6000803e3d6000fd5b505050506040513d602081101561046f57600080fd5b50516001600160a01b0316815260208101919091526040016000205490506102a4565b6000816040516020018082805190602001908083835b602083106104c75780518252601f1990920191602091820191016104a8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106105355780518252601f199092019160209182019101610516565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fea265627a7a72315820fff67becf40f76918ab8c2a45a608ec37191aa9e6311d4c4b1b9eac5d2b11ed464736f6c6343000511003260806040523480156200001157600080fd5b5060405162005b3038038062005b30833981810160405260208110156200003757600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055615ac6806200006a6000396000f3fe608060405234801561001057600080fd5b506004361061047f5760003560e01c8063741b252511610257578063b30d442711610146578063dce15449116100c3578063e9af029211610087578063e9af02921461141f578063eabe7d9114611445578063ede4edd01461147b578063f4a433c0146114a1578063f851a440146114c75761047f565b8063dce15449146113af578063dcfbc0c7146113db578063e4028eee146113e3578063e6653f3d1461140f578063e8755446146114175761047f565b8063c488847b1161010a578063c488847b14611290578063ca0af043146112df578063cc7ebdc41461130d578063d02f735114611333578063da3d454c146113795761047f565b8063b30d44271461117d578063bb82aa5e14611185578063bdcdc2581461118d578063bea6b8b8146111c9578063c2998238146111ef5761047f565b8063986ab838116101d4578063aa90075411610198578063aa900754146110c1578063abfceffc146110c9578063ac0b0bb71461113f578063b0772d0b14611147578063b21be7fd1461114f5761047f565b8063986ab83814610ea45780639d1b5a0a14610eca578063a76b3fda14610ed2578063a7f0e23114610ef8578063a8b4394814610f1c5761047f565b80638e8f294b1161021b5780638e8f294b14610de15780638ebf636414610e29578063929fe9a114610e4857806394543c1514610e7657806394b2294b14610e9c5761047f565b8063741b252514610d5f5780637dc0d1d014610d8557806387495bad14610d8d57806387f7630314610db35780638c57804e14610dbb5761047f565b80634ada90af116103735780635f5af1aa116102f05780636aa875b5116102b45780636aa875b514610c595780636b79c38d14610c7f5780636d154ea514610ccd5780636d35bf9114610cf3578063731f0c2b14610d395761047f565b80635f5af1aa146109c75780635fc7e71e146109ed578063607ef6c114610a335780636810dfa614610af15780636a56947e14610c1d5761047f565b806352d84d1e1161033757806352d84d1e146108fc57806355ee1fe114610919578063598ee1cb1461093f5780635c7786051461096b5780635ec88c79146109a15761047f565b80634ada90af1461080b5780634e79238f146108135780634ef4c3e11461086d5780634fd42e17146108a357806351dff989146108c05761047f565b806327efe3cb116104015780633c94786f116103c55780633c94786f1461074d57806341c728b91461075557806342cbb15c1461079157806347ef3b3b146107995780634a584432146107e55761047f565b806327efe3cb146106915780632d70db78146106bd578063317b0b77146106dc578063391957d7146106f95780633bcf7ec11461071f5761047f565b80631ededc91116104485780631ededc91146105df57806321af45691461062157806324008a621461064557806324a3d6221461068157806326782247146106895761047f565b80627e3dd21461048457806318c882a5146104a05780631c3db2e0146104ce5780631d504dc6146105815780631d7b33d7146105a7575b600080fd5b61048c6114cf565b604080519115158252519081900360200190f35b61048c600480360360408110156104b657600080fd5b506001600160a01b03813516906020013515156114d4565b61057f600480360360408110156104e457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561050e57600080fd5b82018360208201111561052057600080fd5b803590602001918460208302840111600160201b8311171561054157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611674945050505050565b005b61057f6004803603602081101561059757600080fd5b50356001600160a01b03166116d6565b6105cd600480360360208110156105bd57600080fd5b50356001600160a01b0316611890565b60408051918252519081900360200190f35b61057f600480360360a08110156105f557600080fd5b506001600160a01b038135811691602081013582169160408201351690606081013590608001356118a2565b6106296118a7565b604080516001600160a01b039092168252519081900360200190f35b6105cd6004803603608081101561065b57600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356118b6565b61062961197d565b61062961198c565b61057f600480360360408110156106a757600080fd5b506001600160a01b03813516906020013561199b565b61048c600480360360208110156106d357600080fd5b50351515611a9e565b6105cd600480360360208110156106f257600080fd5b5035611bd8565b61057f6004803603602081101561070f57600080fd5b50356001600160a01b0316611c85565b61048c6004803603604081101561073557600080fd5b506001600160a01b0381351690602001351515611d31565b61048c611ecc565b61057f6004803603608081101561076b57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611edc565b6105cd611ee2565b61057f600480360360c08110156107af57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135611ee7565b6105cd600480360360208110156107fb57600080fd5b50356001600160a01b0316611eef565b6105cd611f01565b61084f6004803603608081101561082957600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611f07565b60408051938452602084019290925282820152519081900360600190f35b6105cd6004803603606081101561088357600080fd5b506001600160a01b03813581169160208101359091169060400135611f41565b6105cd600480360360208110156108b957600080fd5b5035611fe7565b61057f600480360360808110156108d657600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612057565b6106296004803603602081101561091257600080fd5b50356120ab565b6105cd6004803603602081101561092f57600080fd5b50356001600160a01b03166120d2565b61057f6004803603604081101561095557600080fd5b506001600160a01b038135169060200135612157565b61057f6004803603606081101561098157600080fd5b506001600160a01b03813581169160208101359091169060400135612252565b61084f600480360360208110156109b757600080fd5b50356001600160a01b0316612257565b6105cd600480360360208110156109dd57600080fd5b50356001600160a01b031661228c565b6105cd600480360360a0811015610a0357600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135612310565b61057f60048036036040811015610a4957600080fd5b810190602081018135600160201b811115610a6357600080fd5b820183602082011115610a7557600080fd5b803590602001918460208302840111600160201b83111715610a9657600080fd5b919390929091602081019035600160201b811115610ab357600080fd5b820183602082011115610ac557600080fd5b803590602001918460208302840111600160201b83111715610ae657600080fd5b5090925090506124c7565b61057f60048036036080811015610b0757600080fd5b810190602081018135600160201b811115610b2157600080fd5b820183602082011115610b3357600080fd5b803590602001918460208302840111600160201b83111715610b5457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ba357600080fd5b820183602082011115610bb557600080fd5b803590602001918460208302840111600160201b83111715610bd657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050803515159150602001351515612657565b61057f60048036036080811015610c3357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611edc565b6105cd60048036036020811015610c6f57600080fd5b50356001600160a01b03166128a2565b610ca560048036036020811015610c9557600080fd5b50356001600160a01b03166128b4565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61048c60048036036020811015610ce357600080fd5b50356001600160a01b03166128de565b61057f600480360360a0811015610d0957600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356118a2565b61048c60048036036020811015610d4f57600080fd5b50356001600160a01b03166128f3565b61057f60048036036020811015610d7557600080fd5b50356001600160a01b0316612908565b6106296129cb565b6105cd60048036036020811015610da357600080fd5b50356001600160a01b03166129da565b61048c6129f2565b610ca560048036036020811015610dd157600080fd5b50356001600160a01b0316612a02565b610e0760048036036020811015610df757600080fd5b50356001600160a01b0316612a2c565b6040805193151584526020840192909252151582820152519081900360600190f35b61048c60048036036020811015610e3f57600080fd5b50351515612a52565b61048c60048036036040811015610e5e57600080fd5b506001600160a01b0381358116916020013516612b8b565b61048c60048036036020811015610e8c57600080fd5b50356001600160a01b0316612bbe565b6105cd612c80565b6105cd60048036036020811015610eba57600080fd5b50356001600160a01b0316612c86565b610629612c98565b6105cd60048036036020811015610ee857600080fd5b50356001600160a01b0316612cb0565b610f00612e15565b604080516001600160e01b039092168252519081900360200190f35b61057f60048036036060811015610f3257600080fd5b810190602081018135600160201b811115610f4c57600080fd5b820183602082011115610f5e57600080fd5b803590602001918460208302840111600160201b83111715610f7f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610fce57600080fd5b820183602082011115610fe057600080fd5b803590602001918460208302840111600160201b8311171561100157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561105057600080fd5b82018360208201111561106257600080fd5b803590602001918460208302840111600160201b8311171561108357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612e27945050505050565b6105cd612f24565b6110ef600480360360208110156110df57600080fd5b50356001600160a01b0316612f2a565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561112b578181015183820152602001611113565b505050509050019250505060405180910390f35b61048c612fb3565b6110ef612fc3565b6105cd6004803603604081101561116557600080fd5b506001600160a01b0381358116916020013516613025565b61057f613042565b610629613306565b6105cd600480360360808110156111a357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135613315565b6105cd600480360360208110156111df57600080fd5b50356001600160a01b03166133a5565b6110ef6004803603602081101561120557600080fd5b810190602081018135600160201b81111561121f57600080fd5b82018360208201111561123157600080fd5b803590602001918460208302840111600160201b8311171561125257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506133b7945050505050565b6112c6600480360360608110156112a657600080fd5b506001600160a01b0381358116916020810135909116906040013561344e565b6040805192835260208301919091528051918290030190f35b6105cd600480360360408110156112f557600080fd5b506001600160a01b0381358116916020013516613676565b6105cd6004803603602081101561132357600080fd5b50356001600160a01b0316613693565b6105cd600480360360a081101561134957600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356136a5565b6105cd6004803603606081101561138f57600080fd5b506001600160a01b03813581169160208101359091169060400135613859565b610629600480360360408110156113c557600080fd5b506001600160a01b038135169060200135613c3b565b610629613c70565b6105cd600480360360408110156113f957600080fd5b506001600160a01b038135169060200135613c7f565b61048c613e2f565b6105cd613e3f565b61057f6004803603602081101561143557600080fd5b50356001600160a01b0316613e45565b6105cd6004803603606081101561145b57600080fd5b506001600160a01b03813581169160208101359091169060400135613eac565b6105cd6004803603602081101561149157600080fd5b50356001600160a01b0316613ee7565b6105cd600480360360208110156114b757600080fd5b50356001600160a01b03166141fa565b61062961420c565b600181565b6001600160a01b03821660009081526009602052604081205460ff1661152b5760405162461bcd60e51b815260040180806020018281038252602881526020018061594b6028913960400191505060405180910390fd5b600a546001600160a01b031633148061154e57506000546001600160a01b031633145b6115895760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b03163314806115a457506001821515145b6115ee576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b6001600160a01b0383166000818152600c6020908152604091829020805486151560ff199091168117909155825193845283830152606090830181905260069083015265426f72726f7760d01b6080830152517f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09181900360a00190a150805b92915050565b6040805160018082528183019092526060916020808301908038833901905050905082816000815181106116a457fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506116d18183600180612657565b505050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b50516001600160a01b031633146117815760405162461bcd60e51b8152600401808060200182810382526027815260200180615a6b6027913960400191505060405180910390fd5b806001600160a01b031663c1e803346040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156117bc57600080fd5b505af11580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b50511561183a576040805162461bcd60e51b815260206004820152601560248201527f6368616e6765206e6f7420617574686f72697a65640000000000000000000000604482015290519081900360640190fd5b806001600160a01b031663b30d44276040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561187557600080fd5b505af1158015611889573d6000803e3d6000fd5b5050505050565b600f6020526000908152604090205481565b611889565b6015546001600160a01b031681565b6001600160a01b03841660009081526009602052604081205460ff166118de57506009611975565b6118e661588b565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561192a57600080fd5b505afa15801561193e573d6000803e3d6000fd5b505050506040513d602081101561195457600080fd5b505190529050611964868261421b565b61196f8685836143f3565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b6119a3614586565b6119f4576040805162461bcd60e51b815260206004820152601960248201527f6f6e6c792061646d696e2063616e206772616e7420636f6d7000000000000000604482015290519081900360640190fd5b6000611a0083836145af565b90508015611a55576040805162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e7420636f6d7020666f72206772616e740000000000604482015290519081900360640190fd5b604080516001600160a01b03851681526020810184905281517f98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c929181900390910190a1505050565b600a546000906001600160a01b0316331480611ac457506000546001600160a01b031633145b611aff5760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480611b1a57506001821515145b611b64576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b600a8054831515600160b81b810260ff60b81b1990921691909117909155604080516020810192909252808252600582820152645365697a6560d81b6060830152517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de09181900360800190a150805b919050565b600080546001600160a01b03163314611c38576040805162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f7200604482015290519081900360640190fd5b6005805490839055604080518281526020810185905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a160005b9392505050565b6000546001600160a01b03163314611cce5760405162461bcd60e51b81526004018080602001828103825260268152602001806159c26026913960400191505060405180910390fd5b601580546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935281517feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29929181900390910190a15050565b6001600160a01b03821660009081526009602052604081205460ff16611d885760405162461bcd60e51b815260040180806020018281038252602881526020018061594b6028913960400191505060405180910390fd5b600a546001600160a01b0316331480611dab57506000546001600160a01b031633145b611de65760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480611e0157506001821515145b611e4b576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b6001600160a01b0383166000818152600b6020908152604091829020805486151560ff199091168117909155825193845283830152606090830181905260049083015263135a5b9d60e21b6080830152517f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09181900360a00190a150919050565b600a54600160a01b900460ff1681565b50505050565b435b90565b505050505050565b60166020526000908152604090205481565b60065481565b600080600080600080611f1c8a8a8a8a6146e9565b925092509250826011811115611f2e57fe5b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600b602052604081205460ff1615611fa0576040805162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b604482015290519081900360640190fd5b6001600160a01b03841660009081526009602052604090205460ff16611fca5760095b9050611c7e565b611fd384614a21565b611fdd8484614bb5565b6000949350505050565b600080546001600160a01b0316331461200d576120066001600b614d70565b9050611bd3565b6006805490839055604080518281526020810185905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611c7e565b801580156120655750600082115b15611edc576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d81815481106120b857fe5b6000918252602090912001546001600160a01b0316905081565b600080546001600160a01b031633146120f15761200660016010614d70565b600480546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611c7e565b61215f614586565b6121b0576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792061646d696e2063616e2073657420636f6d70207370656564000000604482015290519081900360640190fd5b6121b982612908565b806121dc576001600160a01b0382166000908152601860205260408120556121fe565b6121e4611ee2565b6001600160a01b0383166000908152601860205260409020555b6001600160a01b038216600081815260176020908152604091829020849055815184815291517f386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b39281900390910190a25050565b6116d1565b60008060008060008061226e8760008060006146e9565b92509250925082601181111561228057fe5b97919650945092505050565b600080546001600160a01b031633146122ab5761200660016013614d70565b600a80546001600160a01b038481166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9281900390910190a16000611c7e565b6001600160a01b03851660009081526009602052604081205460ff16158061235157506001600160a01b03851660009081526009602052604090205460ff16155b156123605760095b90506124be565b6000866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123b857600080fd5b505afa1580156123cc573d6000803e3d6000fd5b505050506040513d60208110156123e257600080fd5b505190506123ef87612bbe565b1561243857828110156124335760405162461bcd60e51b81526004018080602001828103825260288152602001806159736028913960400191505060405180910390fd5b6124b8565b60008061244486614dd6565b9193509091506000905082601181111561245a57fe5b146124755781601181111561246b57fe5b93505050506124be565b8061248157600361246b565b600061249d604051806020016040528060055481525085614df6565b9050808611156124b45760119450505050506124be565b5050505b60009150505b95945050505050565b6000546001600160a01b03163314806124ea57506015546001600160a01b031633145b6125255760405162461bcd60e51b81526004018080602001828103825260358152602001806159e86035913960400191505060405180910390fd5b8281811580159061253557508082145b612576576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b8281101561264e5784848281811061258d57fe5b90506020020135601660008989858181106125a457fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106125e457fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f686868481811061262a57fe5b905060200201356040518082815260200191505060405180910390a2600101612579565b50505050505050565b60005b835181101561280457600084828151811061267157fe5b6020908102919091018101516001600160a01b0381166000908152600990925260409091205490915060ff166126ee576040805162461bcd60e51b815260206004820152601560248201527f6d61726b6574206d757374206265206c69737465640000000000000000000000604482015290519081900360640190fd5b600184151514156127b45761270161588b565b6040518060200160405280836001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561274557600080fd5b505afa158015612759573d6000803e3d6000fd5b505050506040513d602081101561276f57600080fd5b50519052905061277f828261421b565b60005b87518110156127b1576127a98389838151811061279b57fe5b6020026020010151846143f3565b600101612782565b50505b600183151514156127fb576127c881614a21565b60005b86518110156127f9576127f1828883815181106127e457fe5b6020026020010151614bb5565b6001016127cb565b505b5060010161265a565b5060005b84518110156118895761286685828151811061282057fe5b60200260200101516014600088858151811061283857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546145af565b6014600087848151811061287657fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101612808565b601a6020526000908152604090205481565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b600c6020526000908152604090205460ff1681565b600b6020526000908152604090205460ff1681565b6001600160a01b0381166000908152601760205260408120549061292a611ee2565b6001600160a01b03841660009081526018602052604081205491925090612952908390614e15565b90506000811180156129645750600083115b15611edc5760006129758285614e57565b6001600160a01b0386166000908152601460205260408120549192509061299c9083614e99565b6001600160a01b0387166000908152601460209081526040808320939093556018905220849055505050505050565b6004546001600160a01b031681565b6000816129e78133614ecf565b6011811115611c7e57fe5b600a54600160b01b900460ff1681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b600a546000906001600160a01b0316331480612a7857506000546001600160a01b031633145b612ab35760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480612ace57506001821515145b612b18576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b600a8054831515600160b01b810260ff60b01b1990921691909117909155604080516020810192909252808252600882820152672a3930b739b332b960c11b6060830152517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de09181900360800190a15090565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff1692915050565b6001600160a01b038116600090815260096020526040812060010154158015612c0457506001600160a01b0382166000908152600c602052604090205460ff1615156001145b801561166e5750816001600160a01b031663173b99046040518163ffffffff1660e01b815260040160206040518083038186803b158015612c4457600080fd5b505afa158015612c58573d6000803e3d6000fd5b505050506040513d6020811015612c6e57600080fd5b5051670de0b6b3a76400001492915050565b60075481565b60176020526000908152604090205481565b73c00e94cb662c3520282e6f5717214004a7f2688890565b600080546001600160a01b03163314612ccf5761200660016012614d70565b6001600160a01b03821660009081526009602052604090205460ff1615612cfc57612006600a6011614d70565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d3557600080fd5b505afa158015612d49573d6000803e3d6000fd5b505050506040513d6020811015612d5f57600080fd5b5050604080516060810182526001808252600060208381018281528486018381526001600160a01b03891684526009909252949091209251835490151560ff19918216178455935191830191909155516003909101805491151591909216179055612dc982614fc5565b612dd2826150ac565b604080516001600160a01b038416815290517fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f9181900360200190a1600061166e565b6a0c097ce7bc90715b34b9f160241b81565b612e2f614586565b612e80576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792061646d696e2063616e2073657420636f6d70207370656564000000604482015290519081900360640190fd5b8251825181148015612e925750815181145b612ecd5760405162461bcd60e51b8152600401808060200182810382526029815260200180615a426029913960400191505060405180910390fd5b60005b8181101561188957612f1c858281518110612ee757fe5b6020026020010151858381518110612efb57fe5b6020026020010151858481518110612f0f57fe5b602002602001015161516a565b600101612ed0565b600e5481565b60608060086000846001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612fa657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f88575b5093979650505050505050565b600a54600160b81b900460ff1681565b6060600d80548060200260200160405190810160405280929190818152602001828054801561301b57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612ffd575b5050505050905090565b601260209081526000928352604080842090915290825290205481565b6002546001600160a01b031633146130a1576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c7920627261696e732063616e206265636f6d6520697473656c66000000604482015290519081900360640190fd5b60006130e96130ae611ee2565b6040518060400160405280601c81526020017f626c6f636b206e756d626572206578636565647320333220626974730000000081525061534d565b905060005b600d5481101561330257600f6000600d838154811061310957fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002054601a6000600d848154811061315957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120829055600d805460199291908590811061319357fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812091909155600d8054600f929190849081106131ce57fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120819055600d805460109183918590811061320857fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120600d80549193506011918391908690811061324357fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902082549091506001600160e01b03166132b157815463ffffffff8516600160e01b026001600160e01b03199091166a0c097ce7bc90715b34b9f160241b176001600160e01b03161782555b80546001600160e01b03166132f857805463ffffffff8516600160e01b026001600160e01b03199091166a0c097ce7bc90715b34b9f160241b176001600160e01b03161781555b50506001016130ee565b5050565b6002546001600160a01b031681565b600a54600090600160b01b900460ff161561336c576040805162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b604482015290519081900360640190fd5b60006133798686856153e7565b90508015613388579050611975565b61339186614a21565b61339b8686614bb5565b61196f8685614bb5565b60186020526000908152604090205481565b60606000825190506060816040519080825280602002602001820160405280156133eb578160200160208202803883390190505b50905060005b8281101561344657600085828151811061340757fe5b6020026020010151905061341b8133614ecf565b601181111561342657fe5b83838151811061343257fe5b6020908102919091010152506001016133f1565b509392505050565b600480546040805163fc57d4df60e01b81526001600160a01b038781169482019490945290516000938493849391169163fc57d4df91602480820192602092909190829003018186803b1580156134a457600080fd5b505afa1580156134b8573d6000803e3d6000fd5b505050506040513d60208110156134ce57600080fd5b5051600480546040805163fc57d4df60e01b81526001600160a01b038a8116948201949094529051939450600093929091169163fc57d4df91602480820192602092909190829003018186803b15801561352757600080fd5b505afa15801561353b573d6000803e3d6000fd5b505050506040513d602081101561355157600080fd5b50519050811580613560575080155b1561357557600d93506000925061366e915050565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156135b057600080fd5b505afa1580156135c4573d6000803e3d6000fd5b505050506040513d60208110156135da57600080fd5b5051905060006135e861588b565b6135f061588b565b6135f861588b565b613620604051806020016040528060065481525060405180602001604052808a815250615493565b9250613648604051806020016040528088815250604051806020016040528088815250615493565b915061365483836154d2565b9050613660818b614df6565b600099509750505050505050505b935093915050565b601360209081526000928352604080842090915290825290205481565b60146020526000908152604090205481565b600a54600090600160b81b900460ff16156136f9576040805162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b604482015290519081900360640190fd5b6001600160a01b03861660009081526009602052604090205460ff16158061373a57506001600160a01b03851660009081526009602052604090205460ff16155b15613746576009612359565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561377f57600080fd5b505afa158015613793573d6000803e3d6000fd5b505050506040513d60208110156137a957600080fd5b505160408051635fe3b56760e01b815290516001600160a01b0392831692891691635fe3b567916004808301926020929190829003018186803b1580156137ef57600080fd5b505afa158015613803573d6000803e3d6000fd5b505050506040513d602081101561381957600080fd5b50516001600160a01b031614613830576002612359565b61383986614a21565b6138438684614bb5565b61384d8685614bb5565b60009695505050505050565b6001600160a01b0383166000908152600c602052604081205460ff16156138ba576040805162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03841660009081526009602052604090205460ff166138e1576009611fc3565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166139d957336001600160a01b0385161461396f576040805162461bcd60e51b815260206004820152601560248201527f73656e646572206d7573742062652063546f6b656e0000000000000000000000604482015290519081900360640190fd5b600061397b3385614ecf565b9050600081601181111561398b57fe5b146139a45780601181111561399c57fe5b915050611c7e565b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff166139d757fe5b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015613a2a57600080fd5b505afa158015613a3e573d6000803e3d6000fd5b505050506040513d6020811015613a5457600080fd5b5051613a6157600d611fc3565b6001600160a01b0384166000908152601660205260409020548015613b4e576000856001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015613abb57600080fd5b505afa158015613acf573d6000803e3d6000fd5b505050506040513d6020811015613ae557600080fd5b505190506000613af58286614e99565b9050828110613b4b576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b50505b600080613b5e86886000886146e9565b91935090915060009050826011811115613b7457fe5b14613b8f57816011811115613b8557fe5b9350505050611c7e565b8015613b9c576004613b85565b613ba461588b565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613be857600080fd5b505afa158015613bfc573d6000803e3d6000fd5b505050506040513d6020811015613c1257600080fd5b505190529050613c22888261421b565b613c2d8888836143f3565b600098975050505050505050565b60086020528160005260406000208181548110613c5457fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b600080546001600160a01b03163314613ca557613c9e60016006614d70565b905061166e565b6001600160a01b0383166000908152600960205260409020805460ff16613cda57613cd260096007614d70565b91505061166e565b613ce261588b565b506040805160208101909152838152613cf961588b565b506040805160208101909152670c7d713b49da00008152613d1a818361550e565b15613d3557613d2b60066008614d70565b935050505061166e565b8415801590613dbe5750600480546040805163fc57d4df60e01b81526001600160a01b038a8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015613d9057600080fd5b505afa158015613da4573d6000803e3d6000fd5b505050506040513d6020811015613dba57600080fd5b5051155b15613dcf57613d2b600d6009614d70565b60018301805490869055604080516001600160a01b03891681526020810183905280820188905290517f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59181900360600190a16000979650505050505050565b600a54600160a81b900460ff1681565b60055481565b613ea981600d805480602002602001604051908101604052809291908181526020018280548015613e9f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613e81575b5050505050611674565b50565b600080613eba8585856153e7565b90508015613ec9579050611c7e565b613ed285614a21565b613edc8585614bb5565b600095945050505050565b6000808290506000806000836001600160a01b031663c37f68e2336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b158015613f4857600080fd5b505afa158015613f5c573d6000803e3d6000fd5b505050506040513d6080811015613f7257600080fd5b508051602082015160409092015190945090925090508215613fc55760405162461bcd60e51b8152600401808060200182810382526025815260200180615a1d6025913960400191505060405180910390fd5b8015613fe257613fd7600c6002614d70565b945050505050611bd3565b6000613fef8733856153e7565b9050801561401057614004600e600383615515565b95505050505050611bd3565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff1661404f5760009650505050505050611bd3565b3360009081526002820160209081526040808320805460ff1916905560088252918290208054835181840281018401909452808452606093928301828280156140c157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116140a3575b5050835193945083925060009150505b8281101561411657896001600160a01b03168482815181106140ef57fe5b60200260200101516001600160a01b0316141561410e57809150614116565b6001016140d1565b5081811061412057fe5b33600090815260086020526040902080548190600019810190811061414157fe5b9060005260206000200160009054906101000a90046001600160a01b031681838154811061416b57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905580546141a482600019830161589e565b50604080516001600160a01b038c16815233602082015281517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a160009c9b505050505050505050505050565b60196020526000908152604090205481565b6000546001600160a01b031681565b6001600160a01b03821660009081526011602090815260408083206019909252822054909161424b6130ae611ee2565b835490915060009061426d9063ffffffff80851691600160e01b900416614e15565b905060008111801561427f5750600083115b156143c85760006142f4876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156142c257600080fd5b505afa1580156142d6573d6000803e3d6000fd5b505050506040513d60208110156142ec57600080fd5b50518761557b565b905060006143028386614e57565b905061430c61588b565b600083116143295760405180602001604052806000815250614333565b6143338284615599565b604080516020810190915288546001600160e01b031681529091506143969061435c90836155cd565b5160408051808201909152601a81527f6e657720696e646578206578636565647320323234206269747300000000000060208201526155f2565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611ee7915050565b8015611ee757835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b6001600160a01b03838116600090815260116020908152604080832080546013845282852095881685529490925290912080546001600160e01b039093169081905590918015801561445257506a0c097ce7bc90715b34b9f160241b82115b1561446857506a0c097ce7bc90715b34b9f160241b5b61447061588b565b60405180602001604052806144858585614e15565b815250905060006144e5886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156142c257600080fd5b905060006144f38284615647565b6001600160a01b0389166000908152601460205260408120549192509061451a9083614e99565b6001600160a01b03808b1660008181526014602090815260409182902085905581518781529081018b905281519495509193928e16927f1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a69281900390910190a350505050505050505050565b600080546001600160a01b03163314806145aa57506002546001600160a01b031633145b905090565b6000806145ba612c98565b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561460657600080fd5b505afa15801561461a573d6000803e3d6000fd5b505050506040513d602081101561463057600080fd5b5051905083158015906146435750808411155b156146e057816001600160a01b031663a9059cbb86866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156146a857600080fd5b505af11580156146bc573d6000803e3d6000fd5b505050506040513d60208110156146d257600080fd5b506000935061166e92505050565b50919392505050565b60008060006146f66158c2565b6001600160a01b0388166000908152600860209081526040808320805482518185028101850190935280835260609383018282801561475e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614740575b50939450600093505050505b81518110156149e257600082828151811061478157fe5b60200260200101519050806001600160a01b031663c37f68e28d6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b1580156147e157600080fd5b505afa1580156147f5573d6000803e3d6000fd5b505050506040513d608081101561480b57600080fd5b508051602082015160408084015160609485015160808b01529389019390935291870191909152935083156148505750600f965060009550859450611f379350505050565b60408051602080820183526001600160a01b0380851660008181526009845285902060010154845260c08a01939093528351808301855260808a0151815260e08a015260048054855163fc57d4df60e01b815291820194909452935192169263fc57d4df9260248083019392829003018186803b1580156148d057600080fd5b505afa1580156148e4573d6000803e3d6000fd5b505050506040513d60208110156148fa57600080fd5b505160a0860181905261491d5750600d965060009550859450611f379350505050565b604080516020810190915260a0860151815261010086015260c085015160e08601516149579161494c91615493565b866101000151615493565b610120860181905260408601518651614971929190615675565b85526101008501516060860151602087015161498e929190615675565b60208601526001600160a01b03818116908c1614156149d9576149bb8561012001518b8760200151615675565b602086018190526101008601516149d3918b90615675565b60208601525b5060010161476a565b50602083015183511115614a085750506020810151905160009450039150829050611f37565b5050805160209091015160009450849350039050611f37565b6001600160a01b0381166000908152601060209081526040808320601a9092528220549091614a516130ae611ee2565b8354909150600090614a739063ffffffff80851691600160e01b900416614e15565b9050600081118015614a855750600083115b15614b8b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015614ac557600080fd5b505afa158015614ad9573d6000803e3d6000fd5b505050506040513d6020811015614aef57600080fd5b505190506000614aff8386614e57565b9050614b0961588b565b60008311614b265760405180602001604052806000815250614b30565b614b308284615599565b604080516020810190915288546001600160e01b03168152909150614b599061435c90836155cd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611889915050565b801561188957835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b6001600160a01b03828116600090815260106020908152604080832080546012845282852095871685529490925290912080546001600160e01b0390931690819055909180158015614c1457506a0c097ce7bc90715b34b9f160241b82115b15614c2a57506a0c097ce7bc90715b34b9f160241b5b614c3261588b565b6040518060200160405280614c478585614e15565b81525090506000866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015614ca457600080fd5b505afa158015614cb8573d6000803e3d6000fd5b505050506040513d6020811015614cce57600080fd5b505190506000614cde8284615647565b6001600160a01b03881660009081526014602052604081205491925090614d059083614e99565b6001600160a01b03808a1660008181526014602090815260409182902085905581518781529081018b905281519495509193928d16927f2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a9281900390910190a3505050505050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836011811115614d9f57fe5b836013811115614dab57fe5b604080519283526020830191909152600082820152519081900360600190a1826011811115611c7e57fe5b6000806000614de98460008060006146e9565b9250925092509193909250565b6000614e0061588b565b614e0a848461569d565b9050611975816156be565b6000611c7e83836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f7700000000000000000000008152506156cd565b6000611c7e83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250615727565b6000611c7e8383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506157a6565b6001600160a01b0382166000908152600960205260408120805460ff16614efa57600991505061166e565b6001600160a01b038316600090815260028201602052604090205460ff16151560011415614f2c57600091505061166e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff19166001908117909155600883528184208054918201815584529282902090920180549489166001600160a01b031990951685179055815193845283019190915280517f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59281900390910190a15060009392505050565b60005b600d5481101561505957816001600160a01b0316600d8281548110614fe957fe5b6000918252602090912001546001600160a01b03161415615051576040805162461bcd60e51b815260206004820152601460248201527f6d61726b657420616c7265616479206164646564000000000000000000000000604482015290519081900360640190fd5b600101614fc8565b50600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006150b96130ae611ee2565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b031661510f5781546001600160e01b0319166a0c097ce7bc90715b34b9f160241b1782555b80546001600160e01b031661513d5780546001600160e01b0319166a0c097ce7bc90715b34b9f160241b1781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6001600160a01b0383166000908152600960205260409020805460ff166151d8576040805162461bcd60e51b815260206004820152601960248201527f636f6d70206d61726b6574206973206e6f74206c697374656400000000000000604482015290519081900360640190fd5b6001600160a01b0384166000908152601a602052604090205483146152515761520084614a21565b6001600160a01b0384166000818152601a6020908152604091829020869055815186815291517fdeafccd0c0b768b2529f7dcbbe58e155d6023059150b7490ed4535cc3744b92d9281900390910190a25b6001600160a01b0384166000908152601960205260409020548214611edc5761527861588b565b6040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156152bc57600080fd5b505afa1580156152d0573d6000803e3d6000fd5b505050506040513d60208110156152e657600080fd5b5051905290506152f6858261421b565b6001600160a01b038516600081815260196020908152604091829020869055815186815291517f20af8e791cc98f74b2d7a391c80980ca8e5aebf3d4060bf581997b6acae2e5379281900390910190a25050505050565b600081600160201b84106153df5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156153a457818101518382015260200161538c565b50505050905090810190601f1680156153d15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b6001600160a01b03831660009081526009602052604081205460ff1661540e576009611fc3565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16615446576000611fc3565b60008061545685878660006146e9565b9193509091506000905082601181111561546c57fe5b146154865781601181111561547d57fe5b92505050611c7e565b801561384d57600461547d565b61549b61588b565b6040518060200160405280670de0b6b3a76400006154c186600001518660000151614e57565b816154c857fe5b0490529392505050565b6154da61588b565b60405180602001604052806155056154fe8660000151670de0b6b3a7640000614e57565b85516157fb565b90529392505050565b5190511090565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa084601181111561554457fe5b84601381111561555057fe5b604080519283526020830191909152818101859052519081900360600190a183601181111561197557fe5b6000611c7e61559284670de0b6b3a7640000614e57565b83516157fb565b6155a161588b565b60405180602001604052806155056155c7866a0c097ce7bc90715b34b9f160241b614e57565b856157fb565b6155d561588b565b604051806020016040528061550585600001518560000151614e99565b600081600160e01b84106153df5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b60006a0c097ce7bc90715b34b9f160241b615666848460000151614e57565b8161566d57fe5b049392505050565b600061567f61588b565b615689858561569d565b90506124be615697826156be565b84614e99565b6156a561588b565b6040518060200160405280615505856000015185614e57565b51670de0b6b3a7640000900490565b6000818484111561571f5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b505050900390565b6000831580615734575082155b1561574157506000611c7e565b8383028385828161574e57fe5b0414839061579d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b50949350505050565b6000838301828582101561579d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b6000611c7e83836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250600081836158785760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b5082848161588257fe5b04949350505050565b6040518060200160405280600081525090565b8154818355818111156116d1576000838152602090206116d191810190830161592c565b60405180610140016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200161590061588b565b815260200161590d61588b565b815260200161591a61588b565b815260200161592761588b565b905290565b611ee491905b808211156159465760008155600101615932565b509056fe63616e6e6f742070617573652061206d61726b65742074686174206973206e6f74206c697374656443616e206e6f74207265706179206d6f7265207468616e2074686520746f74616c20626f72726f776f6e6c7920706175736520677561726469616e20616e642061646d696e2063616e2070617573656f6e6c792061646d696e2063616e2073657420626f72726f772063617020677561726469616e6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616e2063616e2073657420626f72726f772063617073657869744d61726b65743a206765744163636f756e74536e617073686f74206661696c6564436f6d7074726f6c6c65723a3a5f736574436f6d7053706565647320696e76616c696420696e7075746f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676520627261696e73a265627a7a7231582091615208ad105512182c4a963efbeeaaba2af6637d5296462959dea57e6ac6db64736f6c63430005110032608060405234801561001057600080fd5b50604051610a9a380380610a9a833981810160405260a081101561003357600080fd5b508051602082015160408301516060840151608090940151600080546001600160a01b0319166001600160a01b03831617905592939192909190848484848461007e8585858561008d565b505050505050505050506102bc565b6100a7622014808561017060201b6105f41790919060201c565b6002556100f66100c562201480836101c1602090811b61059b17901c565b6100e4670de0b6b3a7640000866101c160201b61059b1790919060201c565b61017060201b6105f41790919060201c565b6001556101118262201480610170602090811b6105f417901c565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b60006101b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061021a60201b60201c565b90505b92915050565b6000826101d0575060006101bb565b828202828482816101dd57fe5b04146101b85760405162461bcd60e51b8152600401808060200182810382526021815260200180610a796021913960400191505060405180910390fd5b600081836102a65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026b578181015183820152602001610253565b50505050905090810190601f1680156102985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816102b257fe5b0495945050505050565b6107ae806102cb6000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c80638da5cb5b11610081578063b9f9850a1161005b578063b9f9850a146101eb578063f14039de146101f3578063fd2da339146101fb576100b9565b80638da5cb5b14610190578063a385fb96146101b4578063b8168816146101bc576100b9565b806315f24053146100be5780632037f3e7146101005780632191f92a146101315780636e71e2d81461014d5780638726bb8914610188575b600080fd5b6100e7600480360360608110156100d457600080fd5b5080359060208101359060400135610203565b6040805192835260208301919091528051918290030190f35b61012f6004803603608081101561011657600080fd5b508035906020810135906040810135906060013561021f565b005b61013961027a565b604080519115158252519081900360200190f35b6101766004803603606081101561016357600080fd5b508035906020810135906040013561027f565b60408051918252519081900360200190f35b6101766102df565b6101986102e5565b604080516001600160a01b039092168252519081900360200190f35b6101766102f4565b610176600480360360808110156101d257600080fd5b50803590602081013590604081013590606001356102fb565b61017661037a565b610176610380565b610176610386565b600080600061021386868661038c565b90969095509350505050565b6000546001600160a01b031633146102685760405162461bcd60e51b81526004018080602001828103825260268152602001806107546026913960400191505060405180910390fd5b61027484848484610455565b50505050565b600181565b60008261028e575060006102d8565b6102d56102b1836102a5878763ffffffff6104f616565b9063ffffffff61055916565b6102c985670de0b6b3a764000063ffffffff61059b16565b9063ffffffff6105f416565b90505b9392505050565b60015481565b6000546001600160a01b031681565b6220148081565b600080610316670de0b6b3a76400008463ffffffff61055916565b9050600061032587878761038c565b90506000610345670de0b6b3a76400006102c9848663ffffffff61059b16565b905061036e670de0b6b3a76400006102c9836103628c8c8c61027f565b9063ffffffff61059b16565b98975050505050505050565b60035481565b60025481565b60045481565b60008061039a85858561027f565b905060045481116103e0576103d86002546103cc670de0b6b3a76400006102c96001548661059b90919063ffffffff16565b9063ffffffff6104f616565b9150506102d8565b600061040b6002546103cc670de0b6b3a76400006102c960015460045461059b90919063ffffffff16565b905060006104246004548461055990919063ffffffff16565b905061044b826103cc670de0b6b3a76400006102c96003548661059b90919063ffffffff16565b93505050506102d8565b610468846220148063ffffffff6105f416565b6002556104816102b1622014808363ffffffff61059b16565b600155610497826220148063ffffffff6105f416565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b600082820183811015610550576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061055083836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250610636565b6000826105aa57506000610553565b828202828482816105b757fe5b04146105505760405162461bcd60e51b81526004018080602001828103825260218152602001806107336021913960400191505060405180910390fd5b600061055083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506106cd565b600081848411156106c55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561068a578181015183820152602001610672565b50505050905090810190601f1680156106b75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000818361071c5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561068a578181015183820152602001610672565b50600083858161072857fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776f6e6c7920746865206f776e6572206d61792063616c6c20746869732066756e6374696f6e2ea265627a7a7231582046f925e41021178d17fb6770d28206df60eb5dcfb1166013d8b995560e1f065664736f6c63430005110032536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77608060405234801561001057600080fd5b50604051610a72380380610a72833981810160405260a081101561003357600080fd5b508051602082015160408301516060840151608090940151600080546001600160a01b0319166001600160a01b03831617905592939192909190848484848461007e8585858561008d565b505050505050505050506102bc565b6100a7622014808561017060201b6105cc1790919060201c565b6002556100f66100c562201480836101c1602090811b61057317901c565b6100e4670de0b6b3a7640000866101c160201b6105731790919060201c565b61017060201b6105cc1790919060201c565b6001556101118262201480610170602090811b6105cc17901c565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b60006101b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061021a60201b60201c565b90505b92915050565b6000826101d0575060006101bb565b828202828482816101dd57fe5b04146101b85760405162461bcd60e51b8152600401808060200182810382526021815260200180610a516021913960400191505060405180910390fd5b600081836102a65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026b578181015183820152602001610253565b50505050905090810190601f1680156102985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816102b257fe5b0495945050505050565b610786806102cb6000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c80638da5cb5b11610081578063b9f9850a1161005b578063b9f9850a146101d2578063f14039de146101da578063fd2da339146101e2576100b9565b80638da5cb5b14610177578063a385fb961461019b578063b8168816146101a3576100b9565b806315f24053146100be5780632037f3e7146100f95780632191f92a1461012a5780636e71e2d8146101465780638726bb891461016f575b600080fd5b6100e7600480360360608110156100d457600080fd5b50803590602081013590604001356101ea565b60408051918252519081900360200190f35b6101286004803603608081101561010f57600080fd5b5080359060208101359060408101359060600135610201565b005b61013261025c565b604080519115158252519081900360200190f35b6100e76004803603606081101561015c57600080fd5b5080359060208101359060400135610261565b6100e76102b7565b61017f6102bd565b604080516001600160a01b039092168252519081900360200190f35b6100e76102cc565b6100e7600480360360808110156101b957600080fd5b50803590602081013590604081013590606001356102d3565b6100e7610352565b6100e7610358565b6100e761035e565b60006101f7848484610364565b90505b9392505050565b6000546001600160a01b0316331461024a5760405162461bcd60e51b815260040180806020018281038252602681526020018061072c6026913960400191505060405180910390fd5b6102568484848461042d565b50505050565b600181565b600082610270575060006101fa565b6101f761029383610287878763ffffffff6104ce16565b9063ffffffff61053116565b6102ab85670de0b6b3a764000063ffffffff61057316565b9063ffffffff6105cc16565b60015481565b6000546001600160a01b031681565b6220148081565b6000806102ee670de0b6b3a76400008463ffffffff61053116565b905060006102fd878787610364565b9050600061031d670de0b6b3a76400006102ab848663ffffffff61057316565b9050610346670de0b6b3a76400006102ab8361033a8c8c8c610261565b9063ffffffff61057316565b98975050505050505050565b60035481565b60025481565b60045481565b600080610372858585610261565b905060045481116103b8576103b06002546103a4670de0b6b3a76400006102ab6001548661057390919063ffffffff16565b9063ffffffff6104ce16565b9150506101fa565b60006103e36002546103a4670de0b6b3a76400006102ab60015460045461057390919063ffffffff16565b905060006103fc6004548461053190919063ffffffff16565b9050610423826103a4670de0b6b3a76400006102ab6003548661057390919063ffffffff16565b93505050506101fa565b610440846220148063ffffffff6105cc16565b600255610459610293622014808363ffffffff61057316565b60015561046f826220148063ffffffff6105cc16565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b600082820183811015610528576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061052883836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f770081525061060e565b6000826105825750600061052b565b8282028284828161058f57fe5b04146105285760405162461bcd60e51b815260040180806020018281038252602181526020018061070b6021913960400191505060405180910390fd5b600061052883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506106a5565b6000818484111561069d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561066257818101518382015260200161064a565b50505050905090810190601f16801561068f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836106f45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561066257818101518382015260200161064a565b50600083858161070057fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776f6e6c7920746865206f776e6572206d61792063616c6c20746869732066756e6374696f6e2ea265627a7a723158202e4b127b37a8dc3bbcda7c69b711ba801f8ce1922aea2bf8efd29355519ff6e964736f6c63430005110032536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77608060405234801562000010575f80fd5b5060405162000c6238038062000c6283398101604081905262000033916200011b565b818160036200004383826200020d565b5060046200005282826200020d565b5050505050620002d5565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011262000081575f80fd5b81516001600160401b03808211156200009e576200009e6200005d565b604051601f8301601f19908116603f01168101908282118183101715620000c957620000c96200005d565b81604052838152602092508683858801011115620000e5575f80fd5b5f91505b83821015620001085785820183015181830184015290820190620000e9565b5f93810190920192909252949350505050565b5f80604083850312156200012d575f80fd5b82516001600160401b038082111562000144575f80fd5b620001528683870162000071565b9350602085015191508082111562000168575f80fd5b50620001778582860162000071565b9150509250929050565b600181811c908216806200019657607f821691505b602082108103620001b557634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000208575f81815260208120601f850160051c81016020861015620001e35750805b601f850160051c820191505b818110156200020457828155600101620001ef565b5050505b505050565b81516001600160401b038111156200022957620002296200005d565b62000241816200023a845462000181565b84620001bb565b602080601f83116001811462000277575f84156200025f5750858301515b5f19600386901b1c1916600185901b17855562000204565b5f85815260208120601f198616915b82811015620002a75788860151825594840194600190910190840162000286565b5085821015620002c557878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b61097f80620002e35f395ff3fe608060405234801561000f575f80fd5b50600436106100cf575f3560e01c806340c10f191161007d578063a457c2d711610058578063a457c2d7146101a0578063a9059cbb146101b3578063dd62ed3e146101c6575f80fd5b806340c10f191461015b57806370a082311461017057806395d89b4114610198575f80fd5b806323b872dd116100ad57806323b872dd14610126578063313ce567146101395780633950935114610148575f80fd5b806306fdde03146100d3578063095ea7b3146100f157806318160ddd14610114575b5f80fd5b6100db6101fe565b6040516100e891906107da565b60405180910390f35b6101046100ff366004610840565b61028e565b60405190151581526020016100e8565b6002545b6040519081526020016100e8565b610104610134366004610868565b6102a7565b604051601281526020016100e8565b610104610156366004610840565b6102ca565b61016e610169366004610840565b610308565b005b61011861017e3660046108a1565b6001600160a01b03165f9081526020819052604090205490565b6100db610316565b6101046101ae366004610840565b610325565b6101046101c1366004610840565b6103bb565b6101186101d43660046108c1565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b60606003805461020d906108f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610239906108f2565b80156102845780601f1061025b57610100808354040283529160200191610284565b820191905f5260205f20905b81548152906001019060200180831161026757829003601f168201915b5050505050905090565b5f3361029b8185856103c8565b60019150505b92915050565b5f336102b48582856104eb565b6102bf85858561057b565b506001949350505050565b335f8181526001602090815260408083206001600160a01b038716845290915281205490919061029b908290869061030390879061092a565b6103c8565b610312828261071d565b5050565b60606004805461020d906108f2565b335f8181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103ae5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6102bf82868684036103c8565b5f3361029b81858561057b565b6001600160a01b03831661042a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103a5565b6001600160a01b03821661048b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103a5565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811461057557818110156105685760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103a5565b61057584848484036103c8565b50505050565b6001600160a01b0383166105df5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103a5565b6001600160a01b0382166106415760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103a5565b6001600160a01b0383165f90815260208190526040902054818110156106b85760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103a5565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610575565b6001600160a01b0382166107735760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103a5565b8060025f828254610784919061092a565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f6020808352835180828501525f5b81811015610805578581018301518582016040015282016107e9565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461083b575f80fd5b919050565b5f8060408385031215610851575f80fd5b61085a83610825565b946020939093013593505050565b5f805f6060848603121561087a575f80fd5b61088384610825565b925061089160208501610825565b9150604084013590509250925092565b5f602082840312156108b1575f80fd5b6108ba82610825565b9392505050565b5f80604083850312156108d2575f80fd5b6108db83610825565b91506108e960208401610825565b90509250929050565b600181811c9082168061090657607f821691505b60208210810361092457634e487b7160e01b5f52602260045260245ffd5b50919050565b808201808211156102a157634e487b7160e01b5f52601160045260245ffdfea26469706673582212206636ede9469f61b76eaab82fc8d0b8b3d4a97b83b559cd700305c8805b90ece864736f6c63430008150033 \ No newline at end of file diff --git a/benchmark/ethereum/compound/contract/deploy.sol b/benchmark/ethereum/compound/contract/deploy.sol new file mode 100644 index 0000000..35df25b --- /dev/null +++ b/benchmark/ethereum/compound/contract/deploy.sol @@ -0,0 +1,220 @@ +//SPDX-License-Identifier: UNLICENSED + +pragma solidity ^0.8.19; + + +interface Comptroller { + function _setPriceOracle(address newOracle) external returns (uint); + function _supportMarket(address cToken) external returns (uint); + function _setCollateralFactor(address cToken, uint newCollateralFactorMantissa) external returns (uint) ; +} + +interface PriceOracle { + function setUnderlyingPrice(address cToken, uint underlyingPriceMantissa) external; +} + + + +abstract contract BaseDeployer { + string public salt = "default"; + + event Deployed(string name, address addr); + + constructor() { + deploy(); + } + + function setSalt(string memory _salt) public { + salt = _salt; + } + + function deploy() public virtual; + + function deployContract(string memory name, bytes memory bytecode) + internal + returns (address addr) + { + bytes32 s = keccak256(abi.encodePacked(salt)); + assembly { + addr := create2(0, add(bytecode, 0x20), mload(bytecode), s) + if iszero(extcodesize(addr)) { + revert(0, 0) + } + } + emit Deployed(name, addr); + return addr; + } + + function getChainID() internal view returns (uint256 id) { + assembly { + id := chainid() + } + } + +} + +contract Deployer is BaseDeployer { + + + //0x58c88Ae044A5471CC90472bCe34b67a7432Df716 + address public UNIAddr; + + //0x6d1448CeC252968f2E2526f144C7eedf1cb141e5 + address public USDCAddr; + + //0x12b7358f0B1e2874C6114ecFa3Dc73a3a731272F + address public CUNIAddr; + + //0xb0aCfACcE6946eEfE99A774bfb14d44bd276dAca + address public CUSDCAddr; + + //0xA853A791361D00b029baf1efB856578D1C681813 + address public ComptrollerAddr; + + //0x2698e5A048d3b1054c6e6F69c3576C00b1f21891 + address public PriceOracleAddr; + + //0x785B45Af1d4208A8E925a4bD5c08335dbC3ed73e + address public LegacyJumpRateModelAddr; + + //0x1190b6C0ADa8D6cA566e00fFBFc54a7C4eaA2173 + address public JumpRateModelAddr; + + Comptroller comptroller; + PriceOracle priceOracle; + + + function deploy() public override { + deployErc20(); + deployComptroller(); + deployPriceOracle(); + deployInterestRateModels(); + deployCErc20Immutable(); + + + setPriceOracle(); + supportMarket(); + setCtokenPrice(); + setCollateralFactor(); + } + + function setPriceOracle() internal { + comptroller._setPriceOracle(PriceOracleAddr); + } + + function supportMarket() internal { + comptroller._supportMarket(CUNIAddr); + comptroller._supportMarket(CUSDCAddr); + } + + function setCtokenPrice() internal { + priceOracle.setUnderlyingPrice(CUNIAddr, 25022748000000000000); + priceOracle.setUnderlyingPrice(CUSDCAddr, 35721743800000000000000); + } + + function setCollateralFactor() internal { + comptroller._setCollateralFactor(CUNIAddr,800000000000000000); + comptroller._setCollateralFactor(CUSDCAddr,600000000000000000); + } + + + function deployErc20() internal { + bytes + memory bytecode = hex"608060405234801562000010575f80fd5b5060405162000c6238038062000c6283398101604081905262000033916200011b565b818160036200004383826200020d565b5060046200005282826200020d565b5050505050620002d5565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011262000081575f80fd5b81516001600160401b03808211156200009e576200009e6200005d565b604051601f8301601f19908116603f01168101908282118183101715620000c957620000c96200005d565b81604052838152602092508683858801011115620000e5575f80fd5b5f91505b83821015620001085785820183015181830184015290820190620000e9565b5f93810190920192909252949350505050565b5f80604083850312156200012d575f80fd5b82516001600160401b038082111562000144575f80fd5b620001528683870162000071565b9350602085015191508082111562000168575f80fd5b50620001778582860162000071565b9150509250929050565b600181811c908216806200019657607f821691505b602082108103620001b557634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000208575f81815260208120601f850160051c81016020861015620001e35750805b601f850160051c820191505b818110156200020457828155600101620001ef565b5050505b505050565b81516001600160401b038111156200022957620002296200005d565b62000241816200023a845462000181565b84620001bb565b602080601f83116001811462000277575f84156200025f5750858301515b5f19600386901b1c1916600185901b17855562000204565b5f85815260208120601f198616915b82811015620002a75788860151825594840194600190910190840162000286565b5085821015620002c557878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b61097f80620002e35f395ff3fe608060405234801561000f575f80fd5b50600436106100cf575f3560e01c806340c10f191161007d578063a457c2d711610058578063a457c2d7146101a0578063a9059cbb146101b3578063dd62ed3e146101c6575f80fd5b806340c10f191461015b57806370a082311461017057806395d89b4114610198575f80fd5b806323b872dd116100ad57806323b872dd14610126578063313ce567146101395780633950935114610148575f80fd5b806306fdde03146100d3578063095ea7b3146100f157806318160ddd14610114575b5f80fd5b6100db6101fe565b6040516100e891906107da565b60405180910390f35b6101046100ff366004610840565b61028e565b60405190151581526020016100e8565b6002545b6040519081526020016100e8565b610104610134366004610868565b6102a7565b604051601281526020016100e8565b610104610156366004610840565b6102ca565b61016e610169366004610840565b610308565b005b61011861017e3660046108a1565b6001600160a01b03165f9081526020819052604090205490565b6100db610316565b6101046101ae366004610840565b610325565b6101046101c1366004610840565b6103bb565b6101186101d43660046108c1565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b60606003805461020d906108f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610239906108f2565b80156102845780601f1061025b57610100808354040283529160200191610284565b820191905f5260205f20905b81548152906001019060200180831161026757829003601f168201915b5050505050905090565b5f3361029b8185856103c8565b60019150505b92915050565b5f336102b48582856104eb565b6102bf85858561057b565b506001949350505050565b335f8181526001602090815260408083206001600160a01b038716845290915281205490919061029b908290869061030390879061092a565b6103c8565b610312828261071d565b5050565b60606004805461020d906108f2565b335f8181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103ae5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6102bf82868684036103c8565b5f3361029b81858561057b565b6001600160a01b03831661042a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103a5565b6001600160a01b03821661048b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103a5565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811461057557818110156105685760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103a5565b61057584848484036103c8565b50505050565b6001600160a01b0383166105df5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103a5565b6001600160a01b0382166106415760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103a5565b6001600160a01b0383165f90815260208190526040902054818110156106b85760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103a5565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610575565b6001600160a01b0382166107735760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103a5565b8060025f828254610784919061092a565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f6020808352835180828501525f5b81811015610805578581018301518582016040015282016107e9565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461083b575f80fd5b919050565b5f8060408385031215610851575f80fd5b61085a83610825565b946020939093013593505050565b5f805f6060848603121561087a575f80fd5b61088384610825565b925061089160208501610825565b9150604084013590509250925092565b5f602082840312156108b1575f80fd5b6108ba82610825565b9392505050565b5f80604083850312156108d2575f80fd5b6108db83610825565b91506108e960208401610825565b90509250929050565b600181811c9082168061090657607f821691505b60208210810361092457634e487b7160e01b5f52602260045260245ffd5b50919050565b808201808211156102a157634e487b7160e01b5f52601160045260245ffdfea26469706673582212206636ede9469f61b76eaab82fc8d0b8b3d4a97b83b559cd700305c8805b90ece864736f6c63430008150033"; + UNIAddr = deployContract( + "erc20", + // encode with constructor parameters: constructor(string memory tokenName,string memory tokenSymbol) ERC20(tokenName, tokenSymbol) + abi.encodePacked( + bytecode, + abi.encode("UNI","UNI") + ) + ); + USDCAddr = deployContract( + "erc20", + // encode with constructor parameters: constructor(string memory tokenName,string memory tokenSymbol) ERC20(tokenName, tokenSymbol) + abi.encodePacked( + bytecode, + abi.encode("USDC","USDC") + ) + ); + } + + function deployComptroller() internal { + bytes + memory bytecode = hex"60806040523480156200001157600080fd5b5060405162005b3038038062005b30833981810160405260208110156200003757600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055615ac6806200006a6000396000f3fe608060405234801561001057600080fd5b506004361061047f5760003560e01c8063741b252511610257578063b30d442711610146578063dce15449116100c3578063e9af029211610087578063e9af02921461141f578063eabe7d9114611445578063ede4edd01461147b578063f4a433c0146114a1578063f851a440146114c75761047f565b8063dce15449146113af578063dcfbc0c7146113db578063e4028eee146113e3578063e6653f3d1461140f578063e8755446146114175761047f565b8063c488847b1161010a578063c488847b14611290578063ca0af043146112df578063cc7ebdc41461130d578063d02f735114611333578063da3d454c146113795761047f565b8063b30d44271461117d578063bb82aa5e14611185578063bdcdc2581461118d578063bea6b8b8146111c9578063c2998238146111ef5761047f565b8063986ab838116101d4578063aa90075411610198578063aa900754146110c1578063abfceffc146110c9578063ac0b0bb71461113f578063b0772d0b14611147578063b21be7fd1461114f5761047f565b8063986ab83814610ea45780639d1b5a0a14610eca578063a76b3fda14610ed2578063a7f0e23114610ef8578063a8b4394814610f1c5761047f565b80638e8f294b1161021b5780638e8f294b14610de15780638ebf636414610e29578063929fe9a114610e4857806394543c1514610e7657806394b2294b14610e9c5761047f565b8063741b252514610d5f5780637dc0d1d014610d8557806387495bad14610d8d57806387f7630314610db35780638c57804e14610dbb5761047f565b80634ada90af116103735780635f5af1aa116102f05780636aa875b5116102b45780636aa875b514610c595780636b79c38d14610c7f5780636d154ea514610ccd5780636d35bf9114610cf3578063731f0c2b14610d395761047f565b80635f5af1aa146109c75780635fc7e71e146109ed578063607ef6c114610a335780636810dfa614610af15780636a56947e14610c1d5761047f565b806352d84d1e1161033757806352d84d1e146108fc57806355ee1fe114610919578063598ee1cb1461093f5780635c7786051461096b5780635ec88c79146109a15761047f565b80634ada90af1461080b5780634e79238f146108135780634ef4c3e11461086d5780634fd42e17146108a357806351dff989146108c05761047f565b806327efe3cb116104015780633c94786f116103c55780633c94786f1461074d57806341c728b91461075557806342cbb15c1461079157806347ef3b3b146107995780634a584432146107e55761047f565b806327efe3cb146106915780632d70db78146106bd578063317b0b77146106dc578063391957d7146106f95780633bcf7ec11461071f5761047f565b80631ededc91116104485780631ededc91146105df57806321af45691461062157806324008a621461064557806324a3d6221461068157806326782247146106895761047f565b80627e3dd21461048457806318c882a5146104a05780631c3db2e0146104ce5780631d504dc6146105815780631d7b33d7146105a7575b600080fd5b61048c6114cf565b604080519115158252519081900360200190f35b61048c600480360360408110156104b657600080fd5b506001600160a01b03813516906020013515156114d4565b61057f600480360360408110156104e457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561050e57600080fd5b82018360208201111561052057600080fd5b803590602001918460208302840111600160201b8311171561054157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611674945050505050565b005b61057f6004803603602081101561059757600080fd5b50356001600160a01b03166116d6565b6105cd600480360360208110156105bd57600080fd5b50356001600160a01b0316611890565b60408051918252519081900360200190f35b61057f600480360360a08110156105f557600080fd5b506001600160a01b038135811691602081013582169160408201351690606081013590608001356118a2565b6106296118a7565b604080516001600160a01b039092168252519081900360200190f35b6105cd6004803603608081101561065b57600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356118b6565b61062961197d565b61062961198c565b61057f600480360360408110156106a757600080fd5b506001600160a01b03813516906020013561199b565b61048c600480360360208110156106d357600080fd5b50351515611a9e565b6105cd600480360360208110156106f257600080fd5b5035611bd8565b61057f6004803603602081101561070f57600080fd5b50356001600160a01b0316611c85565b61048c6004803603604081101561073557600080fd5b506001600160a01b0381351690602001351515611d31565b61048c611ecc565b61057f6004803603608081101561076b57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611edc565b6105cd611ee2565b61057f600480360360c08110156107af57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135611ee7565b6105cd600480360360208110156107fb57600080fd5b50356001600160a01b0316611eef565b6105cd611f01565b61084f6004803603608081101561082957600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611f07565b60408051938452602084019290925282820152519081900360600190f35b6105cd6004803603606081101561088357600080fd5b506001600160a01b03813581169160208101359091169060400135611f41565b6105cd600480360360208110156108b957600080fd5b5035611fe7565b61057f600480360360808110156108d657600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612057565b6106296004803603602081101561091257600080fd5b50356120ab565b6105cd6004803603602081101561092f57600080fd5b50356001600160a01b03166120d2565b61057f6004803603604081101561095557600080fd5b506001600160a01b038135169060200135612157565b61057f6004803603606081101561098157600080fd5b506001600160a01b03813581169160208101359091169060400135612252565b61084f600480360360208110156109b757600080fd5b50356001600160a01b0316612257565b6105cd600480360360208110156109dd57600080fd5b50356001600160a01b031661228c565b6105cd600480360360a0811015610a0357600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135612310565b61057f60048036036040811015610a4957600080fd5b810190602081018135600160201b811115610a6357600080fd5b820183602082011115610a7557600080fd5b803590602001918460208302840111600160201b83111715610a9657600080fd5b919390929091602081019035600160201b811115610ab357600080fd5b820183602082011115610ac557600080fd5b803590602001918460208302840111600160201b83111715610ae657600080fd5b5090925090506124c7565b61057f60048036036080811015610b0757600080fd5b810190602081018135600160201b811115610b2157600080fd5b820183602082011115610b3357600080fd5b803590602001918460208302840111600160201b83111715610b5457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ba357600080fd5b820183602082011115610bb557600080fd5b803590602001918460208302840111600160201b83111715610bd657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050803515159150602001351515612657565b61057f60048036036080811015610c3357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611edc565b6105cd60048036036020811015610c6f57600080fd5b50356001600160a01b03166128a2565b610ca560048036036020811015610c9557600080fd5b50356001600160a01b03166128b4565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61048c60048036036020811015610ce357600080fd5b50356001600160a01b03166128de565b61057f600480360360a0811015610d0957600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356118a2565b61048c60048036036020811015610d4f57600080fd5b50356001600160a01b03166128f3565b61057f60048036036020811015610d7557600080fd5b50356001600160a01b0316612908565b6106296129cb565b6105cd60048036036020811015610da357600080fd5b50356001600160a01b03166129da565b61048c6129f2565b610ca560048036036020811015610dd157600080fd5b50356001600160a01b0316612a02565b610e0760048036036020811015610df757600080fd5b50356001600160a01b0316612a2c565b6040805193151584526020840192909252151582820152519081900360600190f35b61048c60048036036020811015610e3f57600080fd5b50351515612a52565b61048c60048036036040811015610e5e57600080fd5b506001600160a01b0381358116916020013516612b8b565b61048c60048036036020811015610e8c57600080fd5b50356001600160a01b0316612bbe565b6105cd612c80565b6105cd60048036036020811015610eba57600080fd5b50356001600160a01b0316612c86565b610629612c98565b6105cd60048036036020811015610ee857600080fd5b50356001600160a01b0316612cb0565b610f00612e15565b604080516001600160e01b039092168252519081900360200190f35b61057f60048036036060811015610f3257600080fd5b810190602081018135600160201b811115610f4c57600080fd5b820183602082011115610f5e57600080fd5b803590602001918460208302840111600160201b83111715610f7f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610fce57600080fd5b820183602082011115610fe057600080fd5b803590602001918460208302840111600160201b8311171561100157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561105057600080fd5b82018360208201111561106257600080fd5b803590602001918460208302840111600160201b8311171561108357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612e27945050505050565b6105cd612f24565b6110ef600480360360208110156110df57600080fd5b50356001600160a01b0316612f2a565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561112b578181015183820152602001611113565b505050509050019250505060405180910390f35b61048c612fb3565b6110ef612fc3565b6105cd6004803603604081101561116557600080fd5b506001600160a01b0381358116916020013516613025565b61057f613042565b610629613306565b6105cd600480360360808110156111a357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135613315565b6105cd600480360360208110156111df57600080fd5b50356001600160a01b03166133a5565b6110ef6004803603602081101561120557600080fd5b810190602081018135600160201b81111561121f57600080fd5b82018360208201111561123157600080fd5b803590602001918460208302840111600160201b8311171561125257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506133b7945050505050565b6112c6600480360360608110156112a657600080fd5b506001600160a01b0381358116916020810135909116906040013561344e565b6040805192835260208301919091528051918290030190f35b6105cd600480360360408110156112f557600080fd5b506001600160a01b0381358116916020013516613676565b6105cd6004803603602081101561132357600080fd5b50356001600160a01b0316613693565b6105cd600480360360a081101561134957600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356136a5565b6105cd6004803603606081101561138f57600080fd5b506001600160a01b03813581169160208101359091169060400135613859565b610629600480360360408110156113c557600080fd5b506001600160a01b038135169060200135613c3b565b610629613c70565b6105cd600480360360408110156113f957600080fd5b506001600160a01b038135169060200135613c7f565b61048c613e2f565b6105cd613e3f565b61057f6004803603602081101561143557600080fd5b50356001600160a01b0316613e45565b6105cd6004803603606081101561145b57600080fd5b506001600160a01b03813581169160208101359091169060400135613eac565b6105cd6004803603602081101561149157600080fd5b50356001600160a01b0316613ee7565b6105cd600480360360208110156114b757600080fd5b50356001600160a01b03166141fa565b61062961420c565b600181565b6001600160a01b03821660009081526009602052604081205460ff1661152b5760405162461bcd60e51b815260040180806020018281038252602881526020018061594b6028913960400191505060405180910390fd5b600a546001600160a01b031633148061154e57506000546001600160a01b031633145b6115895760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b03163314806115a457506001821515145b6115ee576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b6001600160a01b0383166000818152600c6020908152604091829020805486151560ff199091168117909155825193845283830152606090830181905260069083015265426f72726f7760d01b6080830152517f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09181900360a00190a150805b92915050565b6040805160018082528183019092526060916020808301908038833901905050905082816000815181106116a457fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506116d18183600180612657565b505050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b50516001600160a01b031633146117815760405162461bcd60e51b8152600401808060200182810382526027815260200180615a6b6027913960400191505060405180910390fd5b806001600160a01b031663c1e803346040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156117bc57600080fd5b505af11580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b50511561183a576040805162461bcd60e51b815260206004820152601560248201527f6368616e6765206e6f7420617574686f72697a65640000000000000000000000604482015290519081900360640190fd5b806001600160a01b031663b30d44276040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561187557600080fd5b505af1158015611889573d6000803e3d6000fd5b5050505050565b600f6020526000908152604090205481565b611889565b6015546001600160a01b031681565b6001600160a01b03841660009081526009602052604081205460ff166118de57506009611975565b6118e661588b565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561192a57600080fd5b505afa15801561193e573d6000803e3d6000fd5b505050506040513d602081101561195457600080fd5b505190529050611964868261421b565b61196f8685836143f3565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b6119a3614586565b6119f4576040805162461bcd60e51b815260206004820152601960248201527f6f6e6c792061646d696e2063616e206772616e7420636f6d7000000000000000604482015290519081900360640190fd5b6000611a0083836145af565b90508015611a55576040805162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e7420636f6d7020666f72206772616e740000000000604482015290519081900360640190fd5b604080516001600160a01b03851681526020810184905281517f98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c929181900390910190a1505050565b600a546000906001600160a01b0316331480611ac457506000546001600160a01b031633145b611aff5760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480611b1a57506001821515145b611b64576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b600a8054831515600160b81b810260ff60b81b1990921691909117909155604080516020810192909252808252600582820152645365697a6560d81b6060830152517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de09181900360800190a150805b919050565b600080546001600160a01b03163314611c38576040805162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f7200604482015290519081900360640190fd5b6005805490839055604080518281526020810185905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a160005b9392505050565b6000546001600160a01b03163314611cce5760405162461bcd60e51b81526004018080602001828103825260268152602001806159c26026913960400191505060405180910390fd5b601580546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935281517feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29929181900390910190a15050565b6001600160a01b03821660009081526009602052604081205460ff16611d885760405162461bcd60e51b815260040180806020018281038252602881526020018061594b6028913960400191505060405180910390fd5b600a546001600160a01b0316331480611dab57506000546001600160a01b031633145b611de65760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480611e0157506001821515145b611e4b576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b6001600160a01b0383166000818152600b6020908152604091829020805486151560ff199091168117909155825193845283830152606090830181905260049083015263135a5b9d60e21b6080830152517f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09181900360a00190a150919050565b600a54600160a01b900460ff1681565b50505050565b435b90565b505050505050565b60166020526000908152604090205481565b60065481565b600080600080600080611f1c8a8a8a8a6146e9565b925092509250826011811115611f2e57fe5b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600b602052604081205460ff1615611fa0576040805162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b604482015290519081900360640190fd5b6001600160a01b03841660009081526009602052604090205460ff16611fca5760095b9050611c7e565b611fd384614a21565b611fdd8484614bb5565b6000949350505050565b600080546001600160a01b0316331461200d576120066001600b614d70565b9050611bd3565b6006805490839055604080518281526020810185905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611c7e565b801580156120655750600082115b15611edc576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d81815481106120b857fe5b6000918252602090912001546001600160a01b0316905081565b600080546001600160a01b031633146120f15761200660016010614d70565b600480546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611c7e565b61215f614586565b6121b0576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792061646d696e2063616e2073657420636f6d70207370656564000000604482015290519081900360640190fd5b6121b982612908565b806121dc576001600160a01b0382166000908152601860205260408120556121fe565b6121e4611ee2565b6001600160a01b0383166000908152601860205260409020555b6001600160a01b038216600081815260176020908152604091829020849055815184815291517f386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b39281900390910190a25050565b6116d1565b60008060008060008061226e8760008060006146e9565b92509250925082601181111561228057fe5b97919650945092505050565b600080546001600160a01b031633146122ab5761200660016013614d70565b600a80546001600160a01b038481166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9281900390910190a16000611c7e565b6001600160a01b03851660009081526009602052604081205460ff16158061235157506001600160a01b03851660009081526009602052604090205460ff16155b156123605760095b90506124be565b6000866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123b857600080fd5b505afa1580156123cc573d6000803e3d6000fd5b505050506040513d60208110156123e257600080fd5b505190506123ef87612bbe565b1561243857828110156124335760405162461bcd60e51b81526004018080602001828103825260288152602001806159736028913960400191505060405180910390fd5b6124b8565b60008061244486614dd6565b9193509091506000905082601181111561245a57fe5b146124755781601181111561246b57fe5b93505050506124be565b8061248157600361246b565b600061249d604051806020016040528060055481525085614df6565b9050808611156124b45760119450505050506124be565b5050505b60009150505b95945050505050565b6000546001600160a01b03163314806124ea57506015546001600160a01b031633145b6125255760405162461bcd60e51b81526004018080602001828103825260358152602001806159e86035913960400191505060405180910390fd5b8281811580159061253557508082145b612576576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b8281101561264e5784848281811061258d57fe5b90506020020135601660008989858181106125a457fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106125e457fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f686868481811061262a57fe5b905060200201356040518082815260200191505060405180910390a2600101612579565b50505050505050565b60005b835181101561280457600084828151811061267157fe5b6020908102919091018101516001600160a01b0381166000908152600990925260409091205490915060ff166126ee576040805162461bcd60e51b815260206004820152601560248201527f6d61726b6574206d757374206265206c69737465640000000000000000000000604482015290519081900360640190fd5b600184151514156127b45761270161588b565b6040518060200160405280836001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561274557600080fd5b505afa158015612759573d6000803e3d6000fd5b505050506040513d602081101561276f57600080fd5b50519052905061277f828261421b565b60005b87518110156127b1576127a98389838151811061279b57fe5b6020026020010151846143f3565b600101612782565b50505b600183151514156127fb576127c881614a21565b60005b86518110156127f9576127f1828883815181106127e457fe5b6020026020010151614bb5565b6001016127cb565b505b5060010161265a565b5060005b84518110156118895761286685828151811061282057fe5b60200260200101516014600088858151811061283857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546145af565b6014600087848151811061287657fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101612808565b601a6020526000908152604090205481565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b600c6020526000908152604090205460ff1681565b600b6020526000908152604090205460ff1681565b6001600160a01b0381166000908152601760205260408120549061292a611ee2565b6001600160a01b03841660009081526018602052604081205491925090612952908390614e15565b90506000811180156129645750600083115b15611edc5760006129758285614e57565b6001600160a01b0386166000908152601460205260408120549192509061299c9083614e99565b6001600160a01b0387166000908152601460209081526040808320939093556018905220849055505050505050565b6004546001600160a01b031681565b6000816129e78133614ecf565b6011811115611c7e57fe5b600a54600160b01b900460ff1681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b600a546000906001600160a01b0316331480612a7857506000546001600160a01b031633145b612ab35760405162461bcd60e51b815260040180806020018281038252602781526020018061599b6027913960400191505060405180910390fd5b6000546001600160a01b0316331480612ace57506001821515145b612b18576040805162461bcd60e51b81526020600482015260166024820152756f6e6c792061646d696e2063616e20756e706175736560501b604482015290519081900360640190fd5b600a8054831515600160b01b810260ff60b01b1990921691909117909155604080516020810192909252808252600882820152672a3930b739b332b960c11b6060830152517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de09181900360800190a15090565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff1692915050565b6001600160a01b038116600090815260096020526040812060010154158015612c0457506001600160a01b0382166000908152600c602052604090205460ff1615156001145b801561166e5750816001600160a01b031663173b99046040518163ffffffff1660e01b815260040160206040518083038186803b158015612c4457600080fd5b505afa158015612c58573d6000803e3d6000fd5b505050506040513d6020811015612c6e57600080fd5b5051670de0b6b3a76400001492915050565b60075481565b60176020526000908152604090205481565b73c00e94cb662c3520282e6f5717214004a7f2688890565b600080546001600160a01b03163314612ccf5761200660016012614d70565b6001600160a01b03821660009081526009602052604090205460ff1615612cfc57612006600a6011614d70565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d3557600080fd5b505afa158015612d49573d6000803e3d6000fd5b505050506040513d6020811015612d5f57600080fd5b5050604080516060810182526001808252600060208381018281528486018381526001600160a01b03891684526009909252949091209251835490151560ff19918216178455935191830191909155516003909101805491151591909216179055612dc982614fc5565b612dd2826150ac565b604080516001600160a01b038416815290517fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f9181900360200190a1600061166e565b6a0c097ce7bc90715b34b9f160241b81565b612e2f614586565b612e80576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792061646d696e2063616e2073657420636f6d70207370656564000000604482015290519081900360640190fd5b8251825181148015612e925750815181145b612ecd5760405162461bcd60e51b8152600401808060200182810382526029815260200180615a426029913960400191505060405180910390fd5b60005b8181101561188957612f1c858281518110612ee757fe5b6020026020010151858381518110612efb57fe5b6020026020010151858481518110612f0f57fe5b602002602001015161516a565b600101612ed0565b600e5481565b60608060086000846001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612fa657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f88575b5093979650505050505050565b600a54600160b81b900460ff1681565b6060600d80548060200260200160405190810160405280929190818152602001828054801561301b57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612ffd575b5050505050905090565b601260209081526000928352604080842090915290825290205481565b6002546001600160a01b031633146130a1576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c7920627261696e732063616e206265636f6d6520697473656c66000000604482015290519081900360640190fd5b60006130e96130ae611ee2565b6040518060400160405280601c81526020017f626c6f636b206e756d626572206578636565647320333220626974730000000081525061534d565b905060005b600d5481101561330257600f6000600d838154811061310957fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002054601a6000600d848154811061315957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120829055600d805460199291908590811061319357fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812091909155600d8054600f929190849081106131ce57fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120819055600d805460109183918590811061320857fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120600d80549193506011918391908690811061324357fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902082549091506001600160e01b03166132b157815463ffffffff8516600160e01b026001600160e01b03199091166a0c097ce7bc90715b34b9f160241b176001600160e01b03161782555b80546001600160e01b03166132f857805463ffffffff8516600160e01b026001600160e01b03199091166a0c097ce7bc90715b34b9f160241b176001600160e01b03161781555b50506001016130ee565b5050565b6002546001600160a01b031681565b600a54600090600160b01b900460ff161561336c576040805162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b604482015290519081900360640190fd5b60006133798686856153e7565b90508015613388579050611975565b61339186614a21565b61339b8686614bb5565b61196f8685614bb5565b60186020526000908152604090205481565b60606000825190506060816040519080825280602002602001820160405280156133eb578160200160208202803883390190505b50905060005b8281101561344657600085828151811061340757fe5b6020026020010151905061341b8133614ecf565b601181111561342657fe5b83838151811061343257fe5b6020908102919091010152506001016133f1565b509392505050565b600480546040805163fc57d4df60e01b81526001600160a01b038781169482019490945290516000938493849391169163fc57d4df91602480820192602092909190829003018186803b1580156134a457600080fd5b505afa1580156134b8573d6000803e3d6000fd5b505050506040513d60208110156134ce57600080fd5b5051600480546040805163fc57d4df60e01b81526001600160a01b038a8116948201949094529051939450600093929091169163fc57d4df91602480820192602092909190829003018186803b15801561352757600080fd5b505afa15801561353b573d6000803e3d6000fd5b505050506040513d602081101561355157600080fd5b50519050811580613560575080155b1561357557600d93506000925061366e915050565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156135b057600080fd5b505afa1580156135c4573d6000803e3d6000fd5b505050506040513d60208110156135da57600080fd5b5051905060006135e861588b565b6135f061588b565b6135f861588b565b613620604051806020016040528060065481525060405180602001604052808a815250615493565b9250613648604051806020016040528088815250604051806020016040528088815250615493565b915061365483836154d2565b9050613660818b614df6565b600099509750505050505050505b935093915050565b601360209081526000928352604080842090915290825290205481565b60146020526000908152604090205481565b600a54600090600160b81b900460ff16156136f9576040805162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b604482015290519081900360640190fd5b6001600160a01b03861660009081526009602052604090205460ff16158061373a57506001600160a01b03851660009081526009602052604090205460ff16155b15613746576009612359565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561377f57600080fd5b505afa158015613793573d6000803e3d6000fd5b505050506040513d60208110156137a957600080fd5b505160408051635fe3b56760e01b815290516001600160a01b0392831692891691635fe3b567916004808301926020929190829003018186803b1580156137ef57600080fd5b505afa158015613803573d6000803e3d6000fd5b505050506040513d602081101561381957600080fd5b50516001600160a01b031614613830576002612359565b61383986614a21565b6138438684614bb5565b61384d8685614bb5565b60009695505050505050565b6001600160a01b0383166000908152600c602052604081205460ff16156138ba576040805162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03841660009081526009602052604090205460ff166138e1576009611fc3565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166139d957336001600160a01b0385161461396f576040805162461bcd60e51b815260206004820152601560248201527f73656e646572206d7573742062652063546f6b656e0000000000000000000000604482015290519081900360640190fd5b600061397b3385614ecf565b9050600081601181111561398b57fe5b146139a45780601181111561399c57fe5b915050611c7e565b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff166139d757fe5b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015613a2a57600080fd5b505afa158015613a3e573d6000803e3d6000fd5b505050506040513d6020811015613a5457600080fd5b5051613a6157600d611fc3565b6001600160a01b0384166000908152601660205260409020548015613b4e576000856001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015613abb57600080fd5b505afa158015613acf573d6000803e3d6000fd5b505050506040513d6020811015613ae557600080fd5b505190506000613af58286614e99565b9050828110613b4b576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b50505b600080613b5e86886000886146e9565b91935090915060009050826011811115613b7457fe5b14613b8f57816011811115613b8557fe5b9350505050611c7e565b8015613b9c576004613b85565b613ba461588b565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613be857600080fd5b505afa158015613bfc573d6000803e3d6000fd5b505050506040513d6020811015613c1257600080fd5b505190529050613c22888261421b565b613c2d8888836143f3565b600098975050505050505050565b60086020528160005260406000208181548110613c5457fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b600080546001600160a01b03163314613ca557613c9e60016006614d70565b905061166e565b6001600160a01b0383166000908152600960205260409020805460ff16613cda57613cd260096007614d70565b91505061166e565b613ce261588b565b506040805160208101909152838152613cf961588b565b506040805160208101909152670c7d713b49da00008152613d1a818361550e565b15613d3557613d2b60066008614d70565b935050505061166e565b8415801590613dbe5750600480546040805163fc57d4df60e01b81526001600160a01b038a8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015613d9057600080fd5b505afa158015613da4573d6000803e3d6000fd5b505050506040513d6020811015613dba57600080fd5b5051155b15613dcf57613d2b600d6009614d70565b60018301805490869055604080516001600160a01b03891681526020810183905280820188905290517f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59181900360600190a16000979650505050505050565b600a54600160a81b900460ff1681565b60055481565b613ea981600d805480602002602001604051908101604052809291908181526020018280548015613e9f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613e81575b5050505050611674565b50565b600080613eba8585856153e7565b90508015613ec9579050611c7e565b613ed285614a21565b613edc8585614bb5565b600095945050505050565b6000808290506000806000836001600160a01b031663c37f68e2336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b158015613f4857600080fd5b505afa158015613f5c573d6000803e3d6000fd5b505050506040513d6080811015613f7257600080fd5b508051602082015160409092015190945090925090508215613fc55760405162461bcd60e51b8152600401808060200182810382526025815260200180615a1d6025913960400191505060405180910390fd5b8015613fe257613fd7600c6002614d70565b945050505050611bd3565b6000613fef8733856153e7565b9050801561401057614004600e600383615515565b95505050505050611bd3565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff1661404f5760009650505050505050611bd3565b3360009081526002820160209081526040808320805460ff1916905560088252918290208054835181840281018401909452808452606093928301828280156140c157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116140a3575b5050835193945083925060009150505b8281101561411657896001600160a01b03168482815181106140ef57fe5b60200260200101516001600160a01b0316141561410e57809150614116565b6001016140d1565b5081811061412057fe5b33600090815260086020526040902080548190600019810190811061414157fe5b9060005260206000200160009054906101000a90046001600160a01b031681838154811061416b57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905580546141a482600019830161589e565b50604080516001600160a01b038c16815233602082015281517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a160009c9b505050505050505050505050565b60196020526000908152604090205481565b6000546001600160a01b031681565b6001600160a01b03821660009081526011602090815260408083206019909252822054909161424b6130ae611ee2565b835490915060009061426d9063ffffffff80851691600160e01b900416614e15565b905060008111801561427f5750600083115b156143c85760006142f4876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156142c257600080fd5b505afa1580156142d6573d6000803e3d6000fd5b505050506040513d60208110156142ec57600080fd5b50518761557b565b905060006143028386614e57565b905061430c61588b565b600083116143295760405180602001604052806000815250614333565b6143338284615599565b604080516020810190915288546001600160e01b031681529091506143969061435c90836155cd565b5160408051808201909152601a81527f6e657720696e646578206578636565647320323234206269747300000000000060208201526155f2565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611ee7915050565b8015611ee757835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b6001600160a01b03838116600090815260116020908152604080832080546013845282852095881685529490925290912080546001600160e01b039093169081905590918015801561445257506a0c097ce7bc90715b34b9f160241b82115b1561446857506a0c097ce7bc90715b34b9f160241b5b61447061588b565b60405180602001604052806144858585614e15565b815250905060006144e5886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156142c257600080fd5b905060006144f38284615647565b6001600160a01b0389166000908152601460205260408120549192509061451a9083614e99565b6001600160a01b03808b1660008181526014602090815260409182902085905581518781529081018b905281519495509193928e16927f1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a69281900390910190a350505050505050505050565b600080546001600160a01b03163314806145aa57506002546001600160a01b031633145b905090565b6000806145ba612c98565b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561460657600080fd5b505afa15801561461a573d6000803e3d6000fd5b505050506040513d602081101561463057600080fd5b5051905083158015906146435750808411155b156146e057816001600160a01b031663a9059cbb86866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156146a857600080fd5b505af11580156146bc573d6000803e3d6000fd5b505050506040513d60208110156146d257600080fd5b506000935061166e92505050565b50919392505050565b60008060006146f66158c2565b6001600160a01b0388166000908152600860209081526040808320805482518185028101850190935280835260609383018282801561475e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614740575b50939450600093505050505b81518110156149e257600082828151811061478157fe5b60200260200101519050806001600160a01b031663c37f68e28d6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060806040518083038186803b1580156147e157600080fd5b505afa1580156147f5573d6000803e3d6000fd5b505050506040513d608081101561480b57600080fd5b508051602082015160408084015160609485015160808b01529389019390935291870191909152935083156148505750600f965060009550859450611f379350505050565b60408051602080820183526001600160a01b0380851660008181526009845285902060010154845260c08a01939093528351808301855260808a0151815260e08a015260048054855163fc57d4df60e01b815291820194909452935192169263fc57d4df9260248083019392829003018186803b1580156148d057600080fd5b505afa1580156148e4573d6000803e3d6000fd5b505050506040513d60208110156148fa57600080fd5b505160a0860181905261491d5750600d965060009550859450611f379350505050565b604080516020810190915260a0860151815261010086015260c085015160e08601516149579161494c91615493565b866101000151615493565b610120860181905260408601518651614971929190615675565b85526101008501516060860151602087015161498e929190615675565b60208601526001600160a01b03818116908c1614156149d9576149bb8561012001518b8760200151615675565b602086018190526101008601516149d3918b90615675565b60208601525b5060010161476a565b50602083015183511115614a085750506020810151905160009450039150829050611f37565b5050805160209091015160009450849350039050611f37565b6001600160a01b0381166000908152601060209081526040808320601a9092528220549091614a516130ae611ee2565b8354909150600090614a739063ffffffff80851691600160e01b900416614e15565b9050600081118015614a855750600083115b15614b8b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015614ac557600080fd5b505afa158015614ad9573d6000803e3d6000fd5b505050506040513d6020811015614aef57600080fd5b505190506000614aff8386614e57565b9050614b0961588b565b60008311614b265760405180602001604052806000815250614b30565b614b308284615599565b604080516020810190915288546001600160e01b03168152909150614b599061435c90836155cd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611889915050565b801561188957835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b6001600160a01b03828116600090815260106020908152604080832080546012845282852095871685529490925290912080546001600160e01b0390931690819055909180158015614c1457506a0c097ce7bc90715b34b9f160241b82115b15614c2a57506a0c097ce7bc90715b34b9f160241b5b614c3261588b565b6040518060200160405280614c478585614e15565b81525090506000866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015614ca457600080fd5b505afa158015614cb8573d6000803e3d6000fd5b505050506040513d6020811015614cce57600080fd5b505190506000614cde8284615647565b6001600160a01b03881660009081526014602052604081205491925090614d059083614e99565b6001600160a01b03808a1660008181526014602090815260409182902085905581518781529081018b905281519495509193928d16927f2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a9281900390910190a3505050505050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836011811115614d9f57fe5b836013811115614dab57fe5b604080519283526020830191909152600082820152519081900360600190a1826011811115611c7e57fe5b6000806000614de98460008060006146e9565b9250925092509193909250565b6000614e0061588b565b614e0a848461569d565b9050611975816156be565b6000611c7e83836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f7700000000000000000000008152506156cd565b6000611c7e83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250615727565b6000611c7e8383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506157a6565b6001600160a01b0382166000908152600960205260408120805460ff16614efa57600991505061166e565b6001600160a01b038316600090815260028201602052604090205460ff16151560011415614f2c57600091505061166e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff19166001908117909155600883528184208054918201815584529282902090920180549489166001600160a01b031990951685179055815193845283019190915280517f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59281900390910190a15060009392505050565b60005b600d5481101561505957816001600160a01b0316600d8281548110614fe957fe5b6000918252602090912001546001600160a01b03161415615051576040805162461bcd60e51b815260206004820152601460248201527f6d61726b657420616c7265616479206164646564000000000000000000000000604482015290519081900360640190fd5b600101614fc8565b50600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006150b96130ae611ee2565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b031661510f5781546001600160e01b0319166a0c097ce7bc90715b34b9f160241b1782555b80546001600160e01b031661513d5780546001600160e01b0319166a0c097ce7bc90715b34b9f160241b1781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6001600160a01b0383166000908152600960205260409020805460ff166151d8576040805162461bcd60e51b815260206004820152601960248201527f636f6d70206d61726b6574206973206e6f74206c697374656400000000000000604482015290519081900360640190fd5b6001600160a01b0384166000908152601a602052604090205483146152515761520084614a21565b6001600160a01b0384166000818152601a6020908152604091829020869055815186815291517fdeafccd0c0b768b2529f7dcbbe58e155d6023059150b7490ed4535cc3744b92d9281900390910190a25b6001600160a01b0384166000908152601960205260409020548214611edc5761527861588b565b6040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156152bc57600080fd5b505afa1580156152d0573d6000803e3d6000fd5b505050506040513d60208110156152e657600080fd5b5051905290506152f6858261421b565b6001600160a01b038516600081815260196020908152604091829020869055815186815291517f20af8e791cc98f74b2d7a391c80980ca8e5aebf3d4060bf581997b6acae2e5379281900390910190a25050505050565b600081600160201b84106153df5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156153a457818101518382015260200161538c565b50505050905090810190601f1680156153d15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b6001600160a01b03831660009081526009602052604081205460ff1661540e576009611fc3565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16615446576000611fc3565b60008061545685878660006146e9565b9193509091506000905082601181111561546c57fe5b146154865781601181111561547d57fe5b92505050611c7e565b801561384d57600461547d565b61549b61588b565b6040518060200160405280670de0b6b3a76400006154c186600001518660000151614e57565b816154c857fe5b0490529392505050565b6154da61588b565b60405180602001604052806155056154fe8660000151670de0b6b3a7640000614e57565b85516157fb565b90529392505050565b5190511090565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa084601181111561554457fe5b84601381111561555057fe5b604080519283526020830191909152818101859052519081900360600190a183601181111561197557fe5b6000611c7e61559284670de0b6b3a7640000614e57565b83516157fb565b6155a161588b565b60405180602001604052806155056155c7866a0c097ce7bc90715b34b9f160241b614e57565b856157fb565b6155d561588b565b604051806020016040528061550585600001518560000151614e99565b600081600160e01b84106153df5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b60006a0c097ce7bc90715b34b9f160241b615666848460000151614e57565b8161566d57fe5b049392505050565b600061567f61588b565b615689858561569d565b90506124be615697826156be565b84614e99565b6156a561588b565b6040518060200160405280615505856000015185614e57565b51670de0b6b3a7640000900490565b6000818484111561571f5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b505050900390565b6000831580615734575082155b1561574157506000611c7e565b8383028385828161574e57fe5b0414839061579d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b50949350505050565b6000838301828582101561579d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b6000611c7e83836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250600081836158785760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156153a457818101518382015260200161538c565b5082848161588257fe5b04949350505050565b6040518060200160405280600081525090565b8154818355818111156116d1576000838152602090206116d191810190830161592c565b60405180610140016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200161590061588b565b815260200161590d61588b565b815260200161591a61588b565b815260200161592761588b565b905290565b611ee491905b808211156159465760008155600101615932565b509056fe63616e6e6f742070617573652061206d61726b65742074686174206973206e6f74206c697374656443616e206e6f74207265706179206d6f7265207468616e2074686520746f74616c20626f72726f776f6e6c7920706175736520677561726469616e20616e642061646d696e2063616e2070617573656f6e6c792061646d696e2063616e2073657420626f72726f772063617020677561726469616e6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616e2063616e2073657420626f72726f772063617073657869744d61726b65743a206765744163636f756e74536e617073686f74206661696c6564436f6d7074726f6c6c65723a3a5f736574436f6d7053706565647320696e76616c696420696e7075746f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676520627261696e73a265627a7a7231582091615208ad105512182c4a963efbeeaaba2af6637d5296462959dea57e6ac6db64736f6c63430005110032"; + ComptrollerAddr = deployContract( + "Comptroller", + // encode with constructor parameters: constructor(address _admin) + abi.encodePacked( + bytecode, + abi.encode(this) + ) + ); + comptroller = Comptroller(ComptrollerAddr); + } + + function deployPriceOracle() internal{ + bytes + memory bytecode = hex"608060405234801561001057600080fd5b506105ae806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806309a8acb01461005c578063127ffda01461008a5780635e9a523c146100b657806366331bba146100ee578063fc57d4df1461010a575b600080fd5b6100886004803603604081101561007257600080fd5b506001600160a01b038135169060200135610130565b005b610088600480360360408110156100a057600080fd5b506001600160a01b0381351690602001356101a8565b6100dc600480360360208110156100cc57600080fd5b50356001600160a01b031661028a565b60408051918252519081900360200190f35b6100f66102a9565b604080519115158252519081900360200190f35b6100dc6004803603602081101561012057600080fd5b50356001600160a01b03166102ae565b6001600160a01b038216600081815260208181526040918290205482519384529083015281810183905260608201839052517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a16001600160a01b03909116600090815260208190526040902055565b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156101e357600080fd5b505afa1580156101f7573d6000803e3d6000fd5b505050506040513d602081101561020d57600080fd5b50516001600160a01b038116600081815260208181526040918290205482519384529083015281810185905260608201859052519192507fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae7919081900360800190a16001600160a01b031660009081526020819052604090205550565b6001600160a01b0381166000908152602081905260409020545b919050565b600181565b60006103f5826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156102ec57600080fd5b505afa158015610300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561032957600080fd5b810190808051604051939291908464010000000082111561034957600080fd5b90830190602082018581111561035e57600080fd5b825164010000000081118282018810171561037857600080fd5b82525081516020918201929091019080838360005b838110156103a557818101518382015260200161038d565b50505050905090810190601f1680156103d25780820380516001836020036101000a031916815260200191505b506040818101905260048152630c68aa8960e31b60208201529250610492915050565b156104095750670de0b6b3a76400006102a4565b600080836001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561044557600080fd5b505afa158015610459573d6000803e3d6000fd5b505050506040513d602081101561046f57600080fd5b50516001600160a01b0316815260208101919091526040016000205490506102a4565b6000816040516020018082805190602001908083835b602083106104c75780518252601f1990920191602091820191016104a8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106105355780518252601f199092019160209182019101610516565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fea265627a7a72315820fff67becf40f76918ab8c2a45a608ec37191aa9e6311d4c4b1b9eac5d2b11ed464736f6c63430005110032"; + PriceOracleAddr = deployContract( + "SimplePriceOracle", + // encode with constructor parameters: constructor(string memory tokenName,string memory tokenSymbol) ERC20(tokenName, tokenSymbol) + abi.encodePacked( + bytecode, + abi.encode() + ) + ); + priceOracle = PriceOracle(PriceOracleAddr); + } + + function deployInterestRateModels() internal{ + bytes + memory jumpRateModelbytecode = hex"608060405234801561001057600080fd5b50604051610a72380380610a72833981810160405260a081101561003357600080fd5b508051602082015160408301516060840151608090940151600080546001600160a01b0319166001600160a01b03831617905592939192909190848484848461007e8585858561008d565b505050505050505050506102bc565b6100a7622014808561017060201b6105cc1790919060201c565b6002556100f66100c562201480836101c1602090811b61057317901c565b6100e4670de0b6b3a7640000866101c160201b6105731790919060201c565b61017060201b6105cc1790919060201c565b6001556101118262201480610170602090811b6105cc17901c565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b60006101b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061021a60201b60201c565b90505b92915050565b6000826101d0575060006101bb565b828202828482816101dd57fe5b04146101b85760405162461bcd60e51b8152600401808060200182810382526021815260200180610a516021913960400191505060405180910390fd5b600081836102a65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026b578181015183820152602001610253565b50505050905090810190601f1680156102985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816102b257fe5b0495945050505050565b610786806102cb6000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c80638da5cb5b11610081578063b9f9850a1161005b578063b9f9850a146101d2578063f14039de146101da578063fd2da339146101e2576100b9565b80638da5cb5b14610177578063a385fb961461019b578063b8168816146101a3576100b9565b806315f24053146100be5780632037f3e7146100f95780632191f92a1461012a5780636e71e2d8146101465780638726bb891461016f575b600080fd5b6100e7600480360360608110156100d457600080fd5b50803590602081013590604001356101ea565b60408051918252519081900360200190f35b6101286004803603608081101561010f57600080fd5b5080359060208101359060408101359060600135610201565b005b61013261025c565b604080519115158252519081900360200190f35b6100e76004803603606081101561015c57600080fd5b5080359060208101359060400135610261565b6100e76102b7565b61017f6102bd565b604080516001600160a01b039092168252519081900360200190f35b6100e76102cc565b6100e7600480360360808110156101b957600080fd5b50803590602081013590604081013590606001356102d3565b6100e7610352565b6100e7610358565b6100e761035e565b60006101f7848484610364565b90505b9392505050565b6000546001600160a01b0316331461024a5760405162461bcd60e51b815260040180806020018281038252602681526020018061072c6026913960400191505060405180910390fd5b6102568484848461042d565b50505050565b600181565b600082610270575060006101fa565b6101f761029383610287878763ffffffff6104ce16565b9063ffffffff61053116565b6102ab85670de0b6b3a764000063ffffffff61057316565b9063ffffffff6105cc16565b60015481565b6000546001600160a01b031681565b6220148081565b6000806102ee670de0b6b3a76400008463ffffffff61053116565b905060006102fd878787610364565b9050600061031d670de0b6b3a76400006102ab848663ffffffff61057316565b9050610346670de0b6b3a76400006102ab8361033a8c8c8c610261565b9063ffffffff61057316565b98975050505050505050565b60035481565b60025481565b60045481565b600080610372858585610261565b905060045481116103b8576103b06002546103a4670de0b6b3a76400006102ab6001548661057390919063ffffffff16565b9063ffffffff6104ce16565b9150506101fa565b60006103e36002546103a4670de0b6b3a76400006102ab60015460045461057390919063ffffffff16565b905060006103fc6004548461053190919063ffffffff16565b9050610423826103a4670de0b6b3a76400006102ab6003548661057390919063ffffffff16565b93505050506101fa565b610440846220148063ffffffff6105cc16565b600255610459610293622014808363ffffffff61057316565b60015561046f826220148063ffffffff6105cc16565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b600082820183811015610528576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061052883836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f770081525061060e565b6000826105825750600061052b565b8282028284828161058f57fe5b04146105285760405162461bcd60e51b815260040180806020018281038252602181526020018061070b6021913960400191505060405180910390fd5b600061052883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506106a5565b6000818484111561069d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561066257818101518382015260200161064a565b50505050905090810190601f16801561068f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836106f45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561066257818101518382015260200161064a565b50600083858161070057fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776f6e6c7920746865206f776e6572206d61792063616c6c20746869732066756e6374696f6e2ea265627a7a723158202e4b127b37a8dc3bbcda7c69b711ba801f8ce1922aea2bf8efd29355519ff6e964736f6c63430005110032536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77"; + + bytes + memory legacyJumpRateModelbytecode = hex"608060405234801561001057600080fd5b50604051610a9a380380610a9a833981810160405260a081101561003357600080fd5b508051602082015160408301516060840151608090940151600080546001600160a01b0319166001600160a01b03831617905592939192909190848484848461007e8585858561008d565b505050505050505050506102bc565b6100a7622014808561017060201b6105f41790919060201c565b6002556100f66100c562201480836101c1602090811b61059b17901c565b6100e4670de0b6b3a7640000866101c160201b61059b1790919060201c565b61017060201b6105f41790919060201c565b6001556101118262201480610170602090811b6105f417901c565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b60006101b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061021a60201b60201c565b90505b92915050565b6000826101d0575060006101bb565b828202828482816101dd57fe5b04146101b85760405162461bcd60e51b8152600401808060200182810382526021815260200180610a796021913960400191505060405180910390fd5b600081836102a65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026b578181015183820152602001610253565b50505050905090810190601f1680156102985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816102b257fe5b0495945050505050565b6107ae806102cb6000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c80638da5cb5b11610081578063b9f9850a1161005b578063b9f9850a146101eb578063f14039de146101f3578063fd2da339146101fb576100b9565b80638da5cb5b14610190578063a385fb96146101b4578063b8168816146101bc576100b9565b806315f24053146100be5780632037f3e7146101005780632191f92a146101315780636e71e2d81461014d5780638726bb8914610188575b600080fd5b6100e7600480360360608110156100d457600080fd5b5080359060208101359060400135610203565b6040805192835260208301919091528051918290030190f35b61012f6004803603608081101561011657600080fd5b508035906020810135906040810135906060013561021f565b005b61013961027a565b604080519115158252519081900360200190f35b6101766004803603606081101561016357600080fd5b508035906020810135906040013561027f565b60408051918252519081900360200190f35b6101766102df565b6101986102e5565b604080516001600160a01b039092168252519081900360200190f35b6101766102f4565b610176600480360360808110156101d257600080fd5b50803590602081013590604081013590606001356102fb565b61017661037a565b610176610380565b610176610386565b600080600061021386868661038c565b90969095509350505050565b6000546001600160a01b031633146102685760405162461bcd60e51b81526004018080602001828103825260268152602001806107546026913960400191505060405180910390fd5b61027484848484610455565b50505050565b600181565b60008261028e575060006102d8565b6102d56102b1836102a5878763ffffffff6104f616565b9063ffffffff61055916565b6102c985670de0b6b3a764000063ffffffff61059b16565b9063ffffffff6105f416565b90505b9392505050565b60015481565b6000546001600160a01b031681565b6220148081565b600080610316670de0b6b3a76400008463ffffffff61055916565b9050600061032587878761038c565b90506000610345670de0b6b3a76400006102c9848663ffffffff61059b16565b905061036e670de0b6b3a76400006102c9836103628c8c8c61027f565b9063ffffffff61059b16565b98975050505050505050565b60035481565b60025481565b60045481565b60008061039a85858561027f565b905060045481116103e0576103d86002546103cc670de0b6b3a76400006102c96001548661059b90919063ffffffff16565b9063ffffffff6104f616565b9150506102d8565b600061040b6002546103cc670de0b6b3a76400006102c960015460045461059b90919063ffffffff16565b905060006104246004548461055990919063ffffffff16565b905061044b826103cc670de0b6b3a76400006102c96003548661059b90919063ffffffff16565b93505050506102d8565b610468846220148063ffffffff6105f416565b6002556104816102b1622014808363ffffffff61059b16565b600155610497826220148063ffffffff6105f416565b60038190556004829055600254600154604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a150505050565b600082820183811015610550576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061055083836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250610636565b6000826105aa57506000610553565b828202828482816105b757fe5b04146105505760405162461bcd60e51b81526004018080602001828103825260218152602001806107336021913960400191505060405180910390fd5b600061055083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506106cd565b600081848411156106c55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561068a578181015183820152602001610672565b50505050905090810190601f1680156106b75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000818361071c5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561068a578181015183820152602001610672565b50600083858161072857fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776f6e6c7920746865206f776e6572206d61792063616c6c20746869732066756e6374696f6e2ea265627a7a7231582046f925e41021178d17fb6770d28206df60eb5dcfb1166013d8b995560e1f065664736f6c63430005110032536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77"; + + + JumpRateModelAddr = deployContract( + "JumpRateModelV2", + // encode with constructor parameters: constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_, address owner_) + abi.encodePacked( + jumpRateModelbytecode, + abi.encode(20000000000000000,180000000000000000,4000000000000000000,800000000000000000,0xc7F999b83Af6DF9e67d0a37Ee7e900bF38b3D013) + ) + ); + + + LegacyJumpRateModelAddr = deployContract( + "LegacyJumpRateModelV2", + // encode with constructor parameters: constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_, address owner_) + abi.encodePacked( + legacyJumpRateModelbytecode, + abi.encode(0,40000000000000000,1090000000000000000,800000000000000000,0xc7F999b83Af6DF9e67d0a37Ee7e900bF38b3D013) + ) + ); + } + + function deployCErc20Immutable() internal { + bytes + memory bytecode =hex"60806040523480156200001157600080fd5b5060405162005dfb38038062005dfb83398181016040526101008110156200003857600080fd5b81516020830151604080850151606086015160808701805193519597949692959194919392820192846401000000008211156200007457600080fd5b9083019060208201858111156200008a57600080fd5b8251640100000000811182820188101715620000a557600080fd5b82525081516020918201929091019080838360005b83811015620000d4578181015183820152602001620000ba565b50505050905090810190601f168015620001025780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200012657600080fd5b9083019060208201858111156200013c57600080fd5b82516401000000008111828201881017156200015757600080fd5b82525081516020918201929091019080838360005b83811015620001865781810151838201526020016200016c565b50505050905090810190601f168015620001b45780820380516001836020036101000a031916815260200191505b506040908152602082015191015160038054610100600160a81b03191633610100021790559092509050620001ef8888888888888862000223565b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055506200090d95505050505050565b6200023e868686868686620002d260201b6200155c1760201c565b601180546001600160a01b0319166001600160a01b038981169190911791829055604080516318160ddd60e01b8152905192909116916318160ddd91600480820192602092909190829003018186803b1580156200029b57600080fd5b505afa158015620002b0573d6000803e3d6000fd5b505050506040513d6020811015620002c757600080fd5b505050505050505050565b60035461010090046001600160a01b03163314620003225760405162461bcd60e51b815260040180806020018281038252602481526020018062005d626024913960400191505060405180910390fd5b600954158015620003335750600a54155b620003705760405162461bcd60e51b815260040180806020018281038252602381526020018062005d866023913960400191505060405180910390fd5b600784905583620003b35760405162461bcd60e51b815260040180806020018281038252603081526020018062005da96030913960400191505060405180910390fd5b6000620003c9876001600160e01b03620004e816565b905080156200041f576040805162461bcd60e51b815260206004820152601a60248201527f73657474696e6720636f6d7074726f6c6c6572206661696c6564000000000000604482015290519081900360640190fd5b620004326001600160e01b036200065016565b600955670de0b6b3a7640000600a5562000455866001600160e01b036200065516565b90508015620004965760405162461bcd60e51b815260040180806020018281038252602281526020018062005dd96022913960400191505060405180910390fd5b8351620004ab9060019060208701906200086b565b508251620004c19060029060208601906200086b565b50506003805460ff90921660ff199283161790556000805490911660011790555050505050565b60035460009061010090046001600160a01b0316331462000522576200051a6001603f6001600160e01b03620007fb16565b90506200064b565b60055460408051623f1ee960e11b815290516001600160a01b0392831692851691627e3dd2916004808301926020929190829003018186803b1580156200056857600080fd5b505afa1580156200057d573d6000803e3d6000fd5b505050506040513d60208110156200059457600080fd5b5051620005e8576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190a160005b9150505b919050565b435b90565b600354600090819061010090046001600160a01b03163314620006925762000689600160426001600160e01b03620007fb16565b9150506200064b565b620006a56001600160e01b036200065016565b60095414620006c55762000689600a60416001600160e01b03620007fb16565b600660009054906101000a90046001600160a01b03169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200071757600080fd5b505afa1580156200072c573d6000803e3d6000fd5b505050506040513d60208110156200074357600080fd5b505162000797576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a1600062000647565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360108111156200082b57fe5b8360508111156200083857fe5b604080519283526020830191909152600082820152519081900360600190a18260108111156200086457fe5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620008ae57805160ff1916838001178555620008de565b82800160010185558215620008de579182015b82811115620008de578251825591602001919060010190620008c1565b50620008ec929150620008f0565b5090565b6200065291905b80821115620008ec5760008155600101620008f7565b615445806200091d6000396000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c80637f1e06be116101bd578063bd6d894d116100f9578063f2b3abbd116100a2578063f851a4401161007c578063f851a44014610b2a578063f8f9da2814610b32578063fca7820b14610b3a578063fe9c44ae14610b5757610341565b8063f2b3abbd14610ac6578063f3fdb15a14610aec578063f5e3c46214610af457610341565b8063db006a75116100d3578063db006a7514610a73578063dd62ed3e14610a90578063e9c714f214610abe57610341565b8063bd6d894d14610a02578063c37f68e214610a0a578063c5ebeaec14610a5657610341565b8063a0712d6811610166578063aa5af0fd11610140578063aa5af0fd14610996578063ae9d70b01461099e578063b2a02ff1146109a6578063b71d1a0c146109dc57610341565b8063a0712d6814610945578063a6afed9514610962578063a9059cbb1461096a57610341565b806395d89b411161019757806395d89b41146107c557806395dd9193146107cd57806399d8c1b4146107f357610341565b80637f1e06be1461077a578063852a12e3146107a05780638f840ddd146107bd57610341565b8063313ce5671161028c5780635fe3b567116102355780636c540baf1161020f5780636c540baf1461073c5780636f307dc31461074457806370a082311461074c57806373acee981461077257610341565b80635fe3b5671461070f578063601a0bf1146107175780636752e7021461073457610341565b80633e941010116102665780633e941010146106c45780634576b5db146106e157806347bd37181461070757610341565b8063313ce567146106785780633af9e669146106965780633b1d21a2146106bc57610341565b8063182df0f5116102ee57806323b872dd116102c857806323b872dd146105f25780632608f81814610628578063267822471461065457610341565b8063182df0f5146104685780631a31d465146104705780631be19560146105cc57610341565b8063173b99041161031f578063173b99041461043257806317bfdfbc1461043a57806318160ddd1461046057610341565b806306fdde0314610346578063095ea7b3146103c35780630e75270214610403575b600080fd5b61034e610b5f565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610388578181015183820152602001610370565b50505050905090810190601f1680156103b55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ef600480360360408110156103d957600080fd5b506001600160a01b038135169060200135610bec565b604080519115158252519081900360200190f35b6104206004803603602081101561041957600080fd5b5035610c59565b60408051918252519081900360200190f35b610420610c6f565b6104206004803603602081101561045057600080fd5b50356001600160a01b0316610c75565b610420610d35565b610420610d3b565b6105ca600480360360e081101561048657600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a0810160808201356401000000008111156104c957600080fd5b8201836020820111156104db57600080fd5b803590602001918460018302840111640100000000831117156104fd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561055057600080fd5b82018360208201111561056257600080fd5b8035906020019184600183028401116401000000008311171561058457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff169150610d9e9050565b005b6105ca600480360360208110156105e257600080fd5b50356001600160a01b0316610e3d565b6103ef6004803603606081101561060857600080fd5b506001600160a01b03813581169160208101359091169060400135610f79565b6104206004803603604081101561063e57600080fd5b506001600160a01b038135169060200135610feb565b61065c611001565b604080516001600160a01b039092168252519081900360200190f35b610680611010565b6040805160ff9092168252519081900360200190f35b610420600480360360208110156106ac57600080fd5b50356001600160a01b0316611019565b6104206110cf565b610420600480360360208110156106da57600080fd5b50356110de565b610420600480360360208110156106f757600080fd5b50356001600160a01b03166110e9565b61042061123e565b61065c611244565b6104206004803603602081101561072d57600080fd5b5035611253565b6104206112ee565b6104206112f9565b61065c6112ff565b6104206004803603602081101561076257600080fd5b50356001600160a01b031661130e565b610420611329565b6105ca6004803603602081101561079057600080fd5b50356001600160a01b03166113df565b610420600480360360208110156107b657600080fd5b5035611496565b6104206114a1565b61034e6114a7565b610420600480360360208110156107e357600080fd5b50356001600160a01b03166114ff565b6105ca600480360360c081101561080957600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561084457600080fd5b82018360208201111561085657600080fd5b8035906020019184600183028401116401000000008311171561087857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156108cb57600080fd5b8201836020820111156108dd57600080fd5b803590602001918460018302840111640100000000831117156108ff57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff16915061155c9050565b6104206004803603602081101561095b57600080fd5b5035611743565b61042061174f565b6103ef6004803603604081101561098057600080fd5b506001600160a01b038135169060200135611aa7565b610420611b18565b610420611b1e565b610420600480360360608110156109bc57600080fd5b506001600160a01b03813581169160208101359091169060400135611bbd565b610420600480360360208110156109f257600080fd5b50356001600160a01b0316611c2e565b610420611cba565b610a3060048036036020811015610a2057600080fd5b50356001600160a01b0316611d76565b604080519485526020850193909352838301919091526060830152519081900360800190f35b61042060048036036020811015610a6c57600080fd5b5035611e0b565b61042060048036036020811015610a8957600080fd5b5035611e16565b61042060048036036040811015610aa657600080fd5b506001600160a01b0381358116916020013516611e21565b610420611e4c565b61042060048036036020811015610adc57600080fd5b50356001600160a01b0316611f5c565b61065c611f96565b61042060048036036060811015610b0a57600080fd5b506001600160a01b03813581169160208101359160409091013516611fa5565b61065c611fbd565b610420611fd1565b61042060048036036020811015610b5057600080fd5b5035612035565b6103ef6120b3565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be45780601f10610bb957610100808354040283529160200191610be4565b820191906000526020600020905b815481529060010190602001808311610bc757829003601f168201915b505050505081565b336000818152600f602090815260408083206001600160a01b03871680855290835281842086905581518681529151939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a360019150505b92915050565b600080610c65836120b8565b509150505b919050565b60085481565b6000805460ff16610cba576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155610ccc61174f565b14610d17576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b610d20826114ff565b90505b6000805460ff19166001179055919050565b600d5481565b6000806000610d48612161565b90925090506000826003811115610d5b57fe5b14610d975760405162461bcd60e51b815260040180806020018281038252603581526020018061535c6035913960400191505060405180910390fd5b9150505b90565b610dac86868686868661155c565b601180546001600160a01b0319166001600160a01b038981169190911791829055604080516318160ddd60e01b8152905192909116916318160ddd91600480820192602092909190829003018186803b158015610e0857600080fd5b505afa158015610e1c573d6000803e3d6000fd5b505050506040513d6020811015610e3257600080fd5b505050505050505050565b6011546001600160a01b0382811691161415610e8a5760405162461bcd60e51b815260040180806020018281038252603281526020018061518b6032913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b158015610ed457600080fd5b505afa158015610ee8573d6000803e3d6000fd5b505050506040513d6020811015610efe57600080fd5b50516003546040805163a9059cbb60e01b81526101009092046001600160a01b03908116600484015260248301849052905192935084169163a9059cbb9160448082019260009290919082900301818387803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b505050505050565b6000805460ff16610fbe576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155610fd433868686612210565b1490506000805460ff191660011790559392505050565b600080610ff8848461249c565b50949350505050565b6004546001600160a01b031681565b60035460ff1681565b6000611023614f9e565b6040518060200160405280611036611cba565b90526001600160a01b0384166000908152600e6020526040812054919250908190611062908490612547565b9092509050600082600381111561107557fe5b146110c7576040805162461bcd60e51b815260206004820152601f60248201527f62616c616e636520636f756c64206e6f742062652063616c63756c6174656400604482015290519081900360640190fd5b949350505050565b60006110d961259b565b905090565b6000610c538261261b565b60035460009061010090046001600160a01b031633146111165761110f6001603f6126af565b9050610c6a565b60055460408051623f1ee960e11b815290516001600160a01b0392831692851691627e3dd2916004808301926020929190829003018186803b15801561115b57600080fd5b505afa15801561116f573d6000803e3d6000fd5b505050506040513d602081101561118557600080fd5b50516111d8576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190a160005b9392505050565b600b5481565b6005546001600160a01b031681565b6000805460ff16611298576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff191681556112aa61174f565b905080156112d0576112c88160108111156112c157fe5b60306126af565b915050610d23565b6112d983612715565b9150506000805460ff19166001179055919050565b666379da05b6000081565b60095481565b6011546001600160a01b031681565b6001600160a01b03166000908152600e602052604090205490565b6000805460ff1661136e576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561138061174f565b146113cb576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b50600b546000805460ff1916600117905590565b60035461010090046001600160a01b0316331461142d5760405162461bcd60e51b815260040180806020018281038252602d8152602001806151ed602d913960400191505060405180910390fd5b601154604080516317066a5760e21b81526001600160a01b03848116600483015291519190921691635c19a95c91602480830192600092919082900301818387803b15801561147b57600080fd5b505af115801561148f573d6000803e3d6000fd5b5050505050565b6000610c5382612848565b600c5481565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610be45780601f10610bb957610100808354040283529160200191610be4565b600080600061150d846128c9565b9092509050600082600381111561152057fe5b146112375760405162461bcd60e51b81526004018080602001828103825260378152602001806152676037913960400191505060405180910390fd5b60035461010090046001600160a01b031633146115aa5760405162461bcd60e51b81526004018080602001828103825260248152602001806151446024913960400191505060405180910390fd5b6009541580156115ba5750600a54155b6115f55760405162461bcd60e51b81526004018080602001828103825260238152602001806151686023913960400191505060405180910390fd5b6007849055836116365760405162461bcd60e51b81526004018080602001828103825260308152602001806151bd6030913960400191505060405180910390fd5b6000611641876110e9565b90508015611696576040805162461bcd60e51b815260206004820152601a60248201527f73657474696e6720636f6d7074726f6c6c6572206661696c6564000000000000604482015290519081900360640190fd5b61169e61297d565b600955670de0b6b3a7640000600a556116b686612981565b905080156116f55760405162461bcd60e51b815260040180806020018281038252602281526020018061521a6022913960400191505060405180910390fd5b8351611708906001906020870190614fb1565b50825161171c906002906020860190614fb1565b50506003805460ff90921660ff199283161790556000805490911660011790555050505050565b600080610c6583612af6565b60008061175a61297d565b6009549091508082141561177357600092505050610d9b565b600061177d61259b565b600b54600c54600a54600654604080516315f2405360e01b815260048101879052602481018690526044810185905290519596509394929391926000926001600160a01b03909216916315f24053916064808301926020929190829003018186803b1580156117eb57600080fd5b505afa1580156117ff573d6000803e3d6000fd5b505050506040513d602081101561181557600080fd5b5051905065048c27395000811115611874576040805162461bcd60e51b815260206004820152601c60248201527f626f72726f772072617465206973206162737572646c79206869676800000000604482015290519081900360640190fd5b6000806118818989612b77565b9092509050600082600381111561189457fe5b146118e6576040805162461bcd60e51b815260206004820152601f60248201527f636f756c64206e6f742063616c63756c61746520626c6f636b2064656c746100604482015290519081900360640190fd5b6118ee614f9e565b60008060008061190c60405180602001604052808a81525087612b9a565b9097509450600087600381111561191f57fe5b146119515761193c6009600689600381111561193757fe5b612c02565b9e505050505050505050505050505050610d9b565b61195b858c612547565b9097509350600087600381111561196e57fe5b146119865761193c6009600189600381111561193757fe5b611990848c612c68565b909750925060008760038111156119a357fe5b146119bb5761193c6009600489600381111561193757fe5b6119d66040518060200160405280600854815250858c612c8e565b909750915060008760038111156119e957fe5b14611a015761193c6009600589600381111561193757fe5b611a0c858a8b612c8e565b90975090506000876003811115611a1f57fe5b14611a375761193c6009600389600381111561193757fe5b60098e9055600a819055600b839055600c829055604080518d8152602081018690528082018390526060810185905290517f4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc049181900360800190a160009e50505050505050505050505050505090565b6000805460ff16611aec576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155611b0233338686612210565b1490506000805460ff1916600117905592915050565b600a5481565b6006546000906001600160a01b031663b8168816611b3a61259b565b600b54600c546008546040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060206040518083038186803b158015611b8c57600080fd5b505afa158015611ba0573d6000803e3d6000fd5b505050506040513d6020811015611bb657600080fd5b5051905090565b6000805460ff16611c02576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19169055611c1833858585612cea565b90506000805460ff191660011790559392505050565b60035460009061010090046001600160a01b03163314611c545761110f600160456126af565b600480546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000611237565b6000805460ff16611cff576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155611d1161174f565b14611d5c576040805162461bcd60e51b81526020600482015260166024820152751858d8dc9d59481a5b9d195c995cdd0819985a5b195960521b604482015290519081900360640190fd5b611d64610d3b565b90506000805460ff1916600117905590565b6001600160a01b0381166000908152600e6020526040812054819081908190818080611da1896128c9565b935090506000816003811115611db357fe5b14611dd15760095b975060009650869550859450611e049350505050565b611dd9612161565b925090506000816003811115611deb57fe5b14611df7576009611dbb565b5060009650919450925090505b9193509193565b6000610c53826130c4565b6000610c5382613143565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b6004546000906001600160a01b031633141580611e67575033155b15611e7f57611e78600160006126af565b9050610d9b565b60038054600480546001600160a01b0381811661010081810274ffffffffffffffffffffffffffffffffffffffff0019871617968790556001600160a01b031990931690935560408051948390048216808652929095041660208401528351909391927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a1600454604080516001600160a01b038085168252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a160009250505090565b600080611f6761174f565b90508015611f8d57611f85816010811115611f7e57fe5b60406126af565b915050610c6a565b61123783612981565b6006546001600160a01b031681565b600080611fb38585856131bd565b5095945050505050565b60035461010090046001600160a01b031681565b6006546000906001600160a01b03166315f24053611fed61259b565b600b54600c546040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015611b8c57600080fd5b6000805460ff1661207a576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561208c61174f565b905080156120aa576112c88160108111156120a357fe5b60466126af565b6112d9836132ef565b600181565b60008054819060ff166120ff576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561211161174f565b9050801561213c5761212f81601081111561212857fe5b60366126af565b92506000915061214d9050565b612147333386613397565b92509250505b6000805460ff191660011790559092909150565b600d5460009081908061217c5750506007546000915061220c565b600061218661259b565b90506000612192614f9e565b60006121a384600b54600c546136e5565b9350905060008160038111156121b557fe5b146121ca5795506000945061220c9350505050565b6121d48386613723565b9250905060008160038111156121e657fe5b146121fb5795506000945061220c9350505050565b505160009550935061220c92505050565b9091565b600554604080516317b9b84b60e31b81523060048201526001600160a01b03868116602483015285811660448301526064820185905291516000938493169163bdcdc25891608480830192602092919082900301818787803b15801561227557600080fd5b505af1158015612289573d6000803e3d6000fd5b505050506040513d602081101561229f57600080fd5b5051905080156122be576122b66003604a83612c02565b9150506110c7565b836001600160a01b0316856001600160a01b031614156122e4576122b66002604b6126af565b60006001600160a01b038781169087161415612303575060001961232b565b506001600160a01b038086166000908152600f60209081526040808320938a16835292905220545b60008060008061233b8589612b77565b9094509250600084600381111561234e57fe5b1461236c5761235f6009604b6126af565b96505050505050506110c7565b6001600160a01b038a166000908152600e602052604090205461238f9089612b77565b909450915060008460038111156123a257fe5b146123b35761235f6009604c6126af565b6001600160a01b0389166000908152600e60205260409020546123d69089612c68565b909450905060008460038111156123e957fe5b146123fa5761235f6009604d6126af565b6001600160a01b03808b166000908152600e6020526040808220859055918b168152208190556000198514612452576001600160a01b03808b166000908152600f60209081526040808320938f168352929052208390555b886001600160a01b03168a6001600160a01b03166000805160206152d88339815191528a6040518082815260200191505060405180910390a35060009a9950505050505050505050565b60008054819060ff166124e3576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff191681556124f561174f565b905080156125205761251381601081111561250c57fe5b60356126af565b9250600091506125319050565b61252b338686613397565b92509250505b6000805460ff1916600117905590939092509050565b6000806000612554614f9e565b61255e8686612b9a565b9092509050600082600381111561257157fe5b146125825750915060009050612594565b600061258d826137d3565b9350935050505b9250929050565b601154604080516370a0823160e01b815230600482015290516000926001600160a01b03169182916370a0823191602480820192602092909190829003018186803b1580156125e957600080fd5b505afa1580156125fd573d6000803e3d6000fd5b505050506040513d602081101561261357600080fd5b505191505090565b6000805460ff16612660576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561267261174f565b90508015612690576112c881601081111561268957fe5b604e6126af565b612699836137e2565b509150506000805460ff19166001179055919050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360108111156126de57fe5b8360508111156126ea57fe5b604080519283526020830191909152600082820152519081900360600190a182601081111561123757fe5b600354600090819061010090046001600160a01b0316331461273d57611f85600160316126af565b61274561297d565b6009541461275957611f85600a60336126af565b8261276261259b565b101561277457611f85600e60326126af565b600c5483111561278a57611f85600260346126af565b50600c54828103908111156127d05760405162461bcd60e51b81526004018080602001828103825260248152602001806153ed6024913960400191505060405180910390fd5b600c8190556003546127f09061010090046001600160a01b0316846138ca565b600354604080516101009092046001600160a01b0316825260208201859052818101839052517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e916060908290030190a16000611237565b6000805460ff1661288d576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561289f61174f565b905080156128bd576112c88160108111156128b657fe5b60276126af565b6112d9336000856139c1565b6001600160a01b03811660009081526010602052604081208054829182918291829161290057506000945084935061297892505050565b6129108160000154600a54613e88565b9094509250600084600381111561292357fe5b14612938575091935060009250612978915050565b612946838260010154613ec7565b9094509150600084600381111561295957fe5b1461296e575091935060009250612978915050565b5060009450925050505b915091565b4390565b600354600090819061010090046001600160a01b031633146129a957611f85600160426126af565b6129b161297d565b600954146129c557611f85600a60416126af565b600660009054906101000a90046001600160a01b03169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1657600080fd5b505afa158015612a2a573d6000803e3d6000fd5b505050506040513d6020811015612a4057600080fd5b5051612a93576040805162461bcd60e51b815260206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b03858116918217909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000611237565b60008054819060ff16612b3d576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff19168155612b4f61174f565b90508015612b6d5761212f816010811115612b6657fe5b601e6126af565b6121473385613ef2565b600080838311612b8e575060009050818303612594565b50600390506000612594565b6000612ba4614f9e565b600080612bb5866000015186613e88565b90925090506000826003811115612bc857fe5b14612be757506040805160208101909152600081529092509050612594565b60408051602081019091529081526000969095509350505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846010811115612c3157fe5b846050811115612c3d57fe5b604080519283526020830191909152818101859052519081900360600190a18360108111156110c757fe5b600080838301848110612c8057600092509050612594565b506002915060009050612594565b6000806000612c9b614f9e565b612ca58787612b9a565b90925090506000826003811115612cb857fe5b14612cc95750915060009050612ce2565b612cdb612cd5826137d3565b86612c68565b9350935050505b935093915050565b6005546040805163d02f735160e01b81523060048201526001600160a01b038781166024830152868116604483015285811660648301526084820185905291516000938493169163d02f73519160a480830192602092919082900301818787803b158015612d5757600080fd5b505af1158015612d6b573d6000803e3d6000fd5b505050506040513d6020811015612d8157600080fd5b505190508015612d98576122b66003601b83612c02565b846001600160a01b0316846001600160a01b03161415612dbe576122b66006601c6126af565b612dc661502f565b6001600160a01b0385166000908152600e6020526040902054612de99085612b77565b6020830181905282826003811115612dfd57fe5b6003811115612e0857fe5b9052506000905081516003811115612e1c57fe5b14612e4157612e386009601a8360000151600381111561193757fe5b925050506110c7565b612e60846040518060200160405280666379da05b600008152506142c2565b60808201819052612e729085906142ea565b6060820152612e7f612161565b60c0830181905282826003811115612e9357fe5b6003811115612e9e57fe5b9052506000905081516003811115612eb257fe5b14612f04576040805162461bcd60e51b815260206004820152601860248201527f65786368616e67652072617465206d617468206572726f720000000000000000604482015290519081900360640190fd5b612f2460405180602001604052808360c00151815250826080015161432c565b60a08201819052600c54612f379161434b565b60e0820152600d546080820151612f4e91906142ea565b6101008201526001600160a01b0386166000908152600e60205260409020546060820151612f7c9190612c68565b6040830181905282826003811115612f9057fe5b6003811115612f9b57fe5b9052506000905081516003811115612faf57fe5b14612fcb57612e38600960198360000151600381111561193757fe5b60e0810151600c55610100810151600d556020808201516001600160a01b038088166000818152600e855260408082209490945583860151928b168082529084902092909255606085015183519081529251919390926000805160206152d8833981519152929081900390910190a36080810151604080519182525130916001600160a01b038816916000805160206152d88339815191529181900360200190a360a081015160e082015160408051308152602081019390935282810191909152517fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc59181900360600190a16000979650505050505050565b6000805460ff16613109576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561311b61174f565b90508015613139576112c881601081111561313257fe5b60086126af565b6112d93384614381565b6000805460ff16613188576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561319a61174f565b905080156131b1576112c88160108111156128b657fe5b6112d9338460006139c1565b60008054819060ff16613204576040805162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015290519081900360640190fd5b6000805460ff1916815561321661174f565b905080156132415761323481601081111561322d57fe5b600f6126af565b9250600091506132d89050565b836001600160a01b031663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561327c57600080fd5b505af1158015613290573d6000803e3d6000fd5b505050506040513d60208110156132a657600080fd5b5051905080156132c6576132348160108111156132bf57fe5b60106126af565b6132d233878787614615565b92509250505b6000805460ff191660011790559094909350915050565b60035460009061010090046001600160a01b031633146133155761110f600160476126af565b61331d61297d565b600954146133315761110f600a60486126af565b670de0b6b3a764000082111561334d5761110f600260496126af565b6008805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000611237565b60055460408051631200453160e11b81523060048201526001600160a01b0386811660248301528581166044830152606482018590529151600093849384939116916324008a629160848082019260209290919082900301818787803b15801561340057600080fd5b505af1158015613414573d6000803e3d6000fd5b505050506040513d602081101561342a57600080fd5b50519050801561344e576134416003603883612c02565b925060009150612ce29050565b61345661297d565b6009541461346a57613441600a60396126af565b61347261507c565b6001600160a01b038616600090815260106020526040902060010154606082015261349c866128c9565b60808301819052602083018260038111156134b357fe5b60038111156134be57fe5b90525060009050816020015160038111156134d557fe5b146134ff576134f1600960378360200151600381111561193757fe5b935060009250612ce2915050565b6000198514156135185760808101516040820152613520565b604081018590525b61352e878260400151614b10565b60e08201819052608082015161354391612b77565b60a083018190526020830182600381111561355a57fe5b600381111561356557fe5b905250600090508160200151600381111561357c57fe5b146135b85760405162461bcd60e51b815260040180806020018281038252603a81526020018061529e603a913960400191505060405180910390fd5b6135c8600b548260e00151612b77565b60c08301819052602083018260038111156135df57fe5b60038111156135ea57fe5b905250600090508160200151600381111561360157fe5b1461363d5760405162461bcd60e51b81526004018080602001828103825260318152602001806152f86031913960400191505060405180910390fd5b60a080820180516001600160a01b03808a16600081815260106020908152604091829020948555600a5460019095019490945560c0870151600b81905560e088015195518251948f16855294840192909252828101949094526060820192909252608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1929181900390910190a160e00151600097909650945050505050565b6000806000806136f58787612c68565b9092509050600082600381111561370857fe5b146137195750915060009050612ce2565b612cdb8186612b77565b600061372d614f9e565b60008061374286670de0b6b3a7640000613e88565b9092509050600082600381111561375557fe5b1461377457506040805160208101909152600081529092509050612594565b6000806137818388613ec7565b9092509050600082600381111561379457fe5b146137b657506040805160208101909152600081529094509250612594915050565b604080516020810190915290815260009890975095505050505050565b51670de0b6b3a7640000900490565b6000806000806137f061297d565b6009541461380f57613804600a604f6126af565b935091506129789050565b6138193386614b10565b905080600c54019150600c54821015613879576040805162461bcd60e51b815260206004820181905260248201527f61646420726573657276657320756e6578706563746564206f766572666c6f77604482015290519081900360640190fd5b600c829055604080513381526020810183905280820184905290517fa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc59181900360600190a160009350915050915091565b6011546040805163a9059cbb60e01b81526001600160a01b0385811660048301526024820185905291519190921691829163a9059cbb9160448082019260009290919082900301818387803b15801561392257600080fd5b505af1158015613936573d6000803e3d6000fd5b5050505060003d60008114613952576020811461395c57600080fd5b6000199150613968565b60206000803e60005191505b50806139bb576040805162461bcd60e51b815260206004820152601960248201527f544f4b454e5f5452414e534645525f4f55545f4641494c454400000000000000604482015290519081900360640190fd5b50505050565b60008215806139ce575081155b613a095760405162461bcd60e51b81526004018080602001828103825260348152602001806153b96034913960400191505060405180910390fd5b613a116150c2565b613a19612161565b6040830181905260208301826003811115613a3057fe5b6003811115613a3b57fe5b9052506000905081602001516003811115613a5257fe5b14613a7657613a6e6009602b8360200151600381111561193757fe5b915050611237565b8315613af7576060810184905260408051602081018252908201518152613a9d9085612547565b6080830181905260208301826003811115613ab457fe5b6003811115613abf57fe5b9052506000905081602001516003811115613ad657fe5b14613af257613a6e600960298360200151600381111561193757fe5b613b70565b613b138360405180602001604052808460400151815250614d5a565b6060830181905260208301826003811115613b2a57fe5b6003811115613b3557fe5b9052506000905081602001516003811115613b4c57fe5b14613b6857613a6e6009602a8360200151600381111561193757fe5b608081018390525b60055460608201516040805163eabe7d9160e01b81523060048201526001600160a01b03898116602483015260448201939093529051600093929092169163eabe7d919160648082019260209290919082900301818787803b158015613bd557600080fd5b505af1158015613be9573d6000803e3d6000fd5b505050506040513d6020811015613bff57600080fd5b505190508015613c1f57613c166003602883612c02565b92505050611237565b613c2761297d565b60095414613c3b57613c16600a602c6126af565b613c4b600d548360600151612b77565b60a0840181905260208401826003811115613c6257fe5b6003811115613c6d57fe5b9052506000905082602001516003811115613c8457fe5b14613ca057613c166009602e8460200151600381111561193757fe5b6001600160a01b0386166000908152600e60205260409020546060830151613cc89190612b77565b60c0840181905260208401826003811115613cdf57fe5b6003811115613cea57fe5b9052506000905082602001516003811115613d0157fe5b14613d1d57613c166009602d8460200151600381111561193757fe5b8160800151613d2a61259b565b1015613d3c57613c16600e602f6126af565b613d4a8683608001516138ca565b60a0820151600d5560c08201516001600160a01b0387166000818152600e60209081526040918290209390935560608501518151908152905130936000805160206152d8833981519152928290030190a36080820151606080840151604080516001600160a01b038b168152602081019490945283810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9299281900390910190a160055460808301516060840151604080516351dff98960e01b81523060048201526001600160a01b038b81166024830152604482019490945260648101929092525191909216916351dff98991608480830192600092919082900301818387803b158015613e5d57600080fd5b505af1158015613e71573d6000803e3d6000fd5b5060009250613e7e915050565b9695505050505050565b60008083613e9b57506000905080612594565b83830283858281613ea857fe5b0414613ebc57506002915060009050612594565b600092509050612594565b60008082613edb5750600190506000612594565b6000838581613ee657fe5b04915091509250929050565b60055460408051634ef4c3e160e01b81523060048201526001600160a01b03858116602483015260448201859052915160009384938493911691634ef4c3e19160648082019260209290919082900301818787803b158015613f5357600080fd5b505af1158015613f67573d6000803e3d6000fd5b505050506040513d6020811015613f7d57600080fd5b505190508015613fa157613f946003601f83612c02565b9250600091506125949050565b613fa961297d565b60095414613fbd57613f94600a60226126af565b613fc56150c2565b613fcd612161565b6040830181905260208301826003811115613fe457fe5b6003811115613fef57fe5b905250600090508160200151600381111561400657fe5b1461403057614022600960218360200151600381111561193757fe5b935060009250612594915050565b61403a8686614b10565b60c082018190526040805160208101825290830151815261405b9190614d5a565b606083018190526020830182600381111561407257fe5b600381111561407d57fe5b905250600090508160200151600381111561409457fe5b146140e6576040805162461bcd60e51b815260206004820181905260248201527f4d494e545f45584348414e47455f43414c43554c4154494f4e5f4641494c4544604482015290519081900360640190fd5b6140f6600d548260600151612c68565b608083018190526020830182600381111561410d57fe5b600381111561411857fe5b905250600090508160200151600381111561412f57fe5b1461416b5760405162461bcd60e51b81526004018080602001828103825260288152602001806153916028913960400191505060405180910390fd5b6001600160a01b0386166000908152600e602052604090205460608201516141939190612c68565b60a08301819052602083018260038111156141aa57fe5b60038111156141b557fe5b90525060009050816020015160038111156141cc57fe5b146142085760405162461bcd60e51b815260040180806020018281038252602b81526020018061523c602b913960400191505060405180910390fd5b6080810151600d5560a08101516001600160a01b0387166000818152600e60209081526040918290209390935560c084015160608086015183519485529484019190915282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160a01b0388169130916000805160206152d88339815191529181900360200190a360c001516000969095509350505050565b6000670de0b6b3a76400006142db848460000151614d71565b816142e257fe5b049392505050565b600061123783836040518060400160405280601581526020017f7375627472616374696f6e20756e646572666c6f770000000000000000000000815250614db3565b6000614336614f9e565b6143408484614e4a565b90506110c7816137d3565b60006112378383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b815250614e74565b6005546040805163368f515360e21b81523060048201526001600160a01b0385811660248301526044820185905291516000938493169163da3d454c91606480830192602092919082900301818787803b1580156143de57600080fd5b505af11580156143f2573d6000803e3d6000fd5b505050506040513d602081101561440857600080fd5b5051905080156144275761441f6003600e83612c02565b915050610c53565b61442f61297d565b600954146144425761441f600a806126af565b8261444b61259b565b101561445d5761441f600e60096126af565b614465615100565b61446e856128c9565b602083018190528282600381111561448257fe5b600381111561448d57fe5b90525060009050815160038111156144a157fe5b146144c6576144bd600960078360000151600381111561193757fe5b92505050610c53565b6144d4816020015185612c68565b60408301819052828260038111156144e857fe5b60038111156144f357fe5b905250600090508151600381111561450757fe5b14614523576144bd6009600c8360000151600381111561193757fe5b61452f600b5485612c68565b606083018190528282600381111561454357fe5b600381111561454e57fe5b905250600090508151600381111561456257fe5b1461457e576144bd6009600b8360000151600381111561193757fe5b61458885856138ca565b604080820180516001600160a01b03881660008181526010602090815290859020928355600a54600190930192909255606080860151600b81905593518551928352928201899052818501929092529081019190915290517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab809181900360800190a1600095945050505050565b60055460408051632fe3f38f60e11b81523060048201526001600160a01b0384811660248301528781166044830152868116606483015260848201869052915160009384938493911691635fc7e71e9160a48082019260209290919082900301818787803b15801561468657600080fd5b505af115801561469a573d6000803e3d6000fd5b505050506040513d60208110156146b057600080fd5b5051905080156146d4576146c76003601283612c02565b925060009150614b079050565b6146dc61297d565b600954146146f0576146c7600a60166126af565b6146f861297d565b846001600160a01b0316636c540baf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561473157600080fd5b505afa158015614745573d6000803e3d6000fd5b505050506040513d602081101561475b57600080fd5b50511461476e576146c7600a60116126af565b866001600160a01b0316866001600160a01b03161415614794576146c7600660176126af565b846147a5576146c7600760156126af565b6000198514156147bb576146c7600760146126af565b6000806147c9898989613397565b909250905081156147f9576147ea8260108111156147e357fe5b60186126af565b945060009350614b0792505050565b6005546040805163c488847b60e01b81523060048201526001600160a01b038981166024830152604482018590528251600094859492169263c488847b926064808301939192829003018186803b15801561485357600080fd5b505afa158015614867573d6000803e3d6000fd5b505050506040513d604081101561487d57600080fd5b508051602090910151909250905081156148c85760405162461bcd60e51b81526004018080602001828103825260338152602001806153296033913960400191505060405180910390fd5b80886001600160a01b03166370a082318c6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561491f57600080fd5b505afa158015614933573d6000803e3d6000fd5b505050506040513d602081101561494957600080fd5b5051101561499e576040805162461bcd60e51b815260206004820152601860248201527f4c49515549444154455f5345495a455f544f4f5f4d5543480000000000000000604482015290519081900360640190fd5b60006001600160a01b0389163014156149c4576149bd308d8d85612cea565b9050614a4e565b6040805163b2a02ff160e01b81526001600160a01b038e811660048301528d81166024830152604482018590529151918b169163b2a02ff1916064808201926020929091908290030181600087803b158015614a1f57600080fd5b505af1158015614a33573d6000803e3d6000fd5b505050506040513d6020811015614a4957600080fd5b505190505b8015614aa1576040805162461bcd60e51b815260206004820152601460248201527f746f6b656e207365697a757265206661696c6564000000000000000000000000604482015290519081900360640190fd5b604080516001600160a01b03808f168252808e1660208301528183018790528b1660608201526080810184905290517f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb529181900360a00190a16000975092955050505050505b94509492505050565b601154604080516370a0823160e01b815230600482015290516000926001600160a01b031691839183916370a08231916024808301926020929190829003018186803b158015614b5f57600080fd5b505afa158015614b73573d6000803e3d6000fd5b505050506040513d6020811015614b8957600080fd5b5051604080516323b872dd60e01b81526001600160a01b038881166004830152306024830152604482018890529151929350908416916323b872dd9160648082019260009290919082900301818387803b158015614be657600080fd5b505af1158015614bfa573d6000803e3d6000fd5b5050505060003d60008114614c165760208114614c2057600080fd5b6000199150614c2c565b60206000803e60005191505b5080614c7f576040805162461bcd60e51b815260206004820152601860248201527f544f4b454e5f5452414e534645525f494e5f4641494c45440000000000000000604482015290519081900360640190fd5b601154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015614cca57600080fd5b505afa158015614cde573d6000803e3d6000fd5b505050506040513d6020811015614cf457600080fd5b5051905082811015614d4d576040805162461bcd60e51b815260206004820152601a60248201527f544f4b454e5f5452414e534645525f494e5f4f564552464c4f57000000000000604482015290519081900360640190fd5b9190910395945050505050565b6000806000614d67614f9e565b61255e8686614ec9565b600061123783836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250614f28565b60008184841115614e425760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614e07578181015183820152602001614def565b50505050905090810190601f168015614e345780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b614e52614f9e565b6040518060200160405280614e6b856000015185614d71565b90529392505050565b60008383018285821015610ff85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614e07578181015183820152602001614def565b6000614ed3614f9e565b600080614ee8670de0b6b3a764000087613e88565b90925090506000826003811115614efb57fe5b14614f1a57506040805160208101909152600081529092509050612594565b61258d818660000151613723565b6000831580614f35575082155b15614f4257506000611237565b83830283858281614f4f57fe5b04148390610ff85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614e07578181015183820152602001614def565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ff257805160ff191683800117855561501f565b8280016001018555821561501f579182015b8281111561501f578251825591602001919060010190615004565b5061502b929150615129565b5090565b604080516101208101909152806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160e0810190915280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b610d9b91905b8082111561502b576000815560010161512f56fe6f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e63654345726332303a3a7377656570546f6b656e3a2063616e206e6f7420737765657020756e6465726c79696e6720746f6b656e696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e6f6e6c79207468652061646d696e206d6179207365742074686520636f6d702d6c696b652064656c656761746573657474696e6720696e7465726573742072617465206d6f64656c206661696c65644d494e545f4e45575f4143434f554e545f42414c414e43455f43414c43554c4154494f4e5f4641494c4544626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e636553746f726564496e7465726e616c206661696c656452455041595f424f52524f575f4e45575f4143434f554e545f424f52524f575f42414c414e43455f43414c43554c4154494f4e5f4641494c4544ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef52455041595f424f52524f575f4e45575f544f54414c5f42414c414e43455f43414c43554c4154494f4e5f4641494c45444c49515549444154455f434f4d5054524f4c4c45525f43414c43554c4154455f414d4f554e545f5345495a455f4641494c454465786368616e67655261746553746f7265643a2065786368616e67655261746553746f726564496e7465726e616c206661696c65644d494e545f4e45575f544f54414c5f535550504c595f43414c43554c4154494f4e5f4641494c45446f6e65206f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e206d757374206265207a65726f72656475636520726573657276657320756e657870656374656420756e646572666c6f77a265627a7a72315820952b149004d6331a6bdeb8cd0645bbfd988cf14277209b41ab9c7444e28c7e8364736f6c634300051100326f6e6c792061646d696e206d617920696e697469616c697a6520746865206d61726b65746d61726b6574206d6179206f6e6c7920626520696e697469616c697a6564206f6e6365696e697469616c2065786368616e67652072617465206d7573742062652067726561746572207468616e207a65726f2e73657474696e6720696e7465726573742072617465206d6f64656c206661696c6564"; + + CUNIAddr = deployContract( + "CErc20Immutable", + abi.encodePacked( + bytecode, + abi.encode(UNIAddr,ComptrollerAddr,JumpRateModelAddr,200000000000000000000000000,"cUNI","cUNI",8,0xc7F999b83Af6DF9e67d0a37Ee7e900bF38b3D013) + ) + + ); + + CUSDCAddr = deployContract( + "CErc20Immutable", + abi.encodePacked( + bytecode, + abi.encode(USDCAddr,ComptrollerAddr,LegacyJumpRateModelAddr,200000000000000,"cUSDC","cUSDC",8,0xc7F999b83Af6DF9e67d0a37Ee7e900bF38b3D013) + ) + ); + } + +} diff --git a/benchmark/ethereum/compound/eth/eth.toml b/benchmark/ethereum/compound/eth/eth.toml new file mode 100644 index 0000000..3c765d8 --- /dev/null +++ b/benchmark/ethereum/compound/eth/eth.toml @@ -0,0 +1,3 @@ +[rpc] +node = "http://127.0.0.1" +port = "8881" \ No newline at end of file diff --git a/benchmark/ethereum/compound/script.lua b/benchmark/ethereum/compound/script.lua new file mode 100755 index 0000000..c2408c6 --- /dev/null +++ b/benchmark/ethereum/compound/script.lua @@ -0,0 +1,159 @@ +local case = testcase.new() + + +-- Aries +function case:BeforeRun() + -- set contract address + self.blockchain:SetContext('{"contract_name": "UNI", "contract_addr": "0x58c88Ae044A5471CC90472bCe34b67a7432Df716"}') + self.blockchain:SetContext('{"contract_name": "USDC", "contract_addr": "0x6d1448CeC252968f2E2526f144C7eedf1cb141e5"}') + self.blockchain:SetContext('{"contract_name": "CUNI", "contract_addr": "0x12b7358f0B1e2874C6114ecFa3Dc73a3a731272F"}') + self.blockchain:SetContext('{"contract_name": "CUSDC", "contract_addr": "0xb0aCfACcE6946eEfE99A774bfb14d44bd276dAca"}') + self.blockchain:SetContext('{"contract_name": "Comptroller", "contract_addr": "0xA853A791361D00b029baf1efB856578D1C681813"}') + + + local fromAddr = self.blockchain:GetRandomAccountByGroup() + print("from addr:" .. fromAddr) + local uniMint=100000000000000000000 + local usdcMint=100000000000000000000 + local cUNIAddr = self.blockchain:GetContractAddrByName("CUNI") + local cUSDCAddr = self.blockchain:GetContractAddrByName("CUSDC") + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "UNI", + func = "mint", + args = {fromAddr, uniMint}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "UNI", + func = "approve", + args = {cUNIAddr, uniMint}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "USDC", + func = "mint", + args = {fromAddr, usdcMint}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "USDC", + func = "approve", + args = {cUSDCAddr, uniMint}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "Comptroller", + func = "enterOneMarkets", + args = {cUSDCAddr}, + }) + self.blockchain:Invoke({ + caller = fromAddr, + contract = "Comptroller", + func = "enterOneMarkets", + args = {cUNIAddr}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "CUNI", + func = "mint", + args = {uniMint}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "CUSDC", + func = "mint", + args = {usdcMint}, + }) + + +end + + +function case:Run() + local fromAddr = self.blockchain:GetRandomAccountByGroup() + local cUNIAddr = self.blockchain:GetContractAddrByName("CUNI") + local cUSDCAddr = self.blockchain:GetContractAddrByName("CUSDC") + local ctokenArray = {UNIAddr,cUSDCAddr} + local fromAddr = self.blockchain:GetRandomAccountByGroup() + local uniMint=10000000000000000000 + local mintNum=10000000000000000 + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "Comptroller", + func = "enterOneMarkets", + args = {cUSDCAddr}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "Comptroller", + func = "enterOneMarkets", + args = {cUNIAddr}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "UNI", + func = "mint", + args = {fromAddr, uniMint}, + }) + + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "UNI", + func = "approve", + args = {cUNIAddr, mintNum}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "CUNI", + func = "mint", + args = {mintNum}, + }) + + borrowNum=self.toolkit.RandInt(100000, 1000000) + self.blockchain:Invoke({ + caller = fromAddr, + contract = "CUNI", + func = "borrow", + args = {borrowNum}, + }) + + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "UNI", + func = "approve", + args = {cUNIAddr,borrowNum}, + }) + + self.blockchain:Invoke({ + caller = fromAddr, + contract = "CUNI", + func = "repayBorrow", + args = {borrowNum}, + }) + + + + + + + + + + + +end +return case diff --git a/benchmark/ethereum/erc20/config.toml b/benchmark/ethereum/erc20/config.toml new file mode 100755 index 0000000..02e400b --- /dev/null +++ b/benchmark/ethereum/erc20/config.toml @@ -0,0 +1,29 @@ +[engine] +rate = 1000 +duration = "30s" +cap = 1000 +accounts = 1000 + +[client] +script = "benchmark/ethereum/erc20/script.lua" # 脚本 +type = "eth" # 区块链类型 +contract = "benchmark/ethereum/erc20/contract" # 合约目录路径 +contract_num = 1 # 合约部署数量 +config = "benchmark/ethereum/erc20/eth" # 区块链SDK配置路径 +plugin = "./eth.so" # 插件路径 +args = [] # 合约参数路径 + +[client.options] # 客户端选项 + +[recorder.log] +dump=false +dir="./logs" +level="debug" + +[recorder.csv] +dir="./csv" + + + + + diff --git a/benchmark/ethereum/erc20/contract/ERC20.abi b/benchmark/ethereum/erc20/contract/ERC20.abi new file mode 100644 index 0000000..5b15d4d --- /dev/null +++ b/benchmark/ethereum/erc20/contract/ERC20.abi @@ -0,0 +1 @@ +[{"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":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","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"}] \ No newline at end of file diff --git a/benchmark/ethereum/erc20/contract/ERC20.bin b/benchmark/ethereum/erc20/contract/ERC20.bin new file mode 100644 index 0000000..18b2e53 --- /dev/null +++ b/benchmark/ethereum/erc20/contract/ERC20.bin @@ -0,0 +1 @@ +60806040526040518060400160405280601381526020017f5465737420546f6b656e206f6e204178696f6d00000000000000000000000000815250600390816200004a919062000324565b506040518060400160405280600481526020017f5441584d000000000000000000000000000000000000000000000000000000008152506004908162000091919062000324565b50600960055f6101000a81548160ff021916908360ff160217905550348015620000b9575f80fd5b5062000408565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200013c57607f821691505b602082108103620001525762000151620000f7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620001b67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000179565b620001c2868362000179565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200020c620002066200020084620001da565b620001e3565b620001da565b9050919050565b5f819050919050565b6200022783620001ec565b6200023f620002368262000213565b84845462000185565b825550505050565b5f90565b6200025562000247565b620002628184846200021c565b505050565b5b8181101562000289576200027d5f826200024b565b60018101905062000268565b5050565b601f821115620002d857620002a28162000158565b620002ad846200016a565b81016020851015620002bd578190505b620002d5620002cc856200016a565b83018262000267565b50505b505050565b5f82821c905092915050565b5f620002fa5f1984600802620002dd565b1980831691505092915050565b5f620003148383620002e9565b9150826002028217905092915050565b6200032f82620000c0565b67ffffffffffffffff8111156200034b576200034a620000ca565b5b62000357825462000124565b620003648282856200028d565b5f60209050601f8311600181146200039a575f841562000385578287015190505b62000391858262000307565b86555062000400565b601f198416620003aa8662000158565b5f5b82811015620003d357848901518255600182019150602085019450602081019050620003ac565b86831015620003f35784890151620003ef601f891682620002e9565b8355505b6001600288020188555050505b505050505050565b610f5180620004165f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c806342966c681161006f57806342966c681461016557806370a082311461018157806395d89b41146101b1578063a0712d68146101cf578063a9059cbb146101eb578063dd62ed3e1461021b576100a7565b806306fdde03146100ab578063095ea7b3146100c957806318160ddd146100f957806323b872dd14610117578063313ce56714610147575b5f80fd5b6100b361024b565b6040516100c09190610af9565b60405180910390f35b6100e360048036038101906100de9190610baa565b6102d7565b6040516100f09190610c02565b60405180910390f35b6101016103c4565b60405161010e9190610c2a565b60405180910390f35b610131600480360381019061012c9190610c43565b6103cd565b60405161013e9190610c02565b60405180910390f35b61014f610607565b60405161015c9190610cae565b60405180910390f35b61017f600480360381019061017a9190610cc7565b610619565b005b61019b60048036038101906101969190610cf2565b6106eb565b6040516101a89190610c2a565b60405180910390f35b6101b9610730565b6040516101c69190610af9565b60405180910390f35b6101e960048036038101906101e49190610cc7565b6107bc565b005b61020560048036038101906102009190610baa565b61088e565b6040516102129190610c02565b60405180910390f35b61023560048036038101906102309190610d1d565b6109ed565b6040516102429190610c2a565b60405180910390f35b6003805461025890610d88565b80601f016020809104026020016040519081016040528092919081815260200182805461028490610d88565b80156102cf5780601f106102a6576101008083540402835291602001916102cf565b820191905f5260205f20905b8154815290600101906020018083116102b257829003601f168201915b505050505081565b5f8160015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516103b29190610c2a565b60405180910390a36001905092915050565b5f600254905090565b5f816103d985336109ed565b101561041a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041190610e02565b60405180910390fd5b81610424856106eb565b1015610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045c90610e6a565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546104ec9190610eb5565b92505081905550815f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461053e9190610eb5565b92505081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546105909190610ee8565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516105f49190610c2a565b60405180910390a3600190509392505050565b60055f9054906101000a900460ff1681565b805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546106649190610eb5565b925050819055508060025f82825461067c9190610eb5565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516106e09190610c2a565b60405180910390a350565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6004805461073d90610d88565b80601f016020809104026020016040519081016040528092919081815260200182805461076990610d88565b80156107b45780601f1061078b576101008083540402835291602001916107b4565b820191905f5260205f20905b81548152906001019060200180831161079757829003601f168201915b505050505081565b805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108079190610ee8565b925050819055508060025f82825461081f9190610ee8565b925050819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516108839190610c2a565b60405180910390a350565b5f81610899336106eb565b10156108da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d190610e6a565b60405180910390fd5b815f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546109259190610eb5565b92505081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546109779190610ee8565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109db9190610c2a565b60405180910390a36001905092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015610aa6578082015181840152602081019050610a8b565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610acb82610a6f565b610ad58185610a79565b9350610ae5818560208601610a89565b610aee81610ab1565b840191505092915050565b5f6020820190508181035f830152610b118184610ac1565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610b4682610b1d565b9050919050565b610b5681610b3c565b8114610b60575f80fd5b50565b5f81359050610b7181610b4d565b92915050565b5f819050919050565b610b8981610b77565b8114610b93575f80fd5b50565b5f81359050610ba481610b80565b92915050565b5f8060408385031215610bc057610bbf610b19565b5b5f610bcd85828601610b63565b9250506020610bde85828601610b96565b9150509250929050565b5f8115159050919050565b610bfc81610be8565b82525050565b5f602082019050610c155f830184610bf3565b92915050565b610c2481610b77565b82525050565b5f602082019050610c3d5f830184610c1b565b92915050565b5f805f60608486031215610c5a57610c59610b19565b5b5f610c6786828701610b63565b9350506020610c7886828701610b63565b9250506040610c8986828701610b96565b9150509250925092565b5f60ff82169050919050565b610ca881610c93565b82525050565b5f602082019050610cc15f830184610c9f565b92915050565b5f60208284031215610cdc57610cdb610b19565b5b5f610ce984828501610b96565b91505092915050565b5f60208284031215610d0757610d06610b19565b5b5f610d1484828501610b63565b91505092915050565b5f8060408385031215610d3357610d32610b19565b5b5f610d4085828601610b63565b9250506020610d5185828601610b63565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610d9f57607f821691505b602082108103610db257610db1610d5b565b5b50919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f610dec601683610a79565b9150610df782610db8565b602082019050919050565b5f6020820190508181035f830152610e1981610de0565b9050919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f610e54601483610a79565b9150610e5f82610e20565b602082019050919050565b5f6020820190508181035f830152610e8181610e48565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610ebf82610b77565b9150610eca83610b77565b9250828203905081811115610ee257610ee1610e88565b5b92915050565b5f610ef282610b77565b9150610efd83610b77565b9250828201905080821115610f1557610f14610e88565b5b9291505056fea26469706673582212206e636d78cd340b4f6d0535d1e3f54aa4ccd5659bc61d1b99772a33de3c8f51b964736f6c63430008150033 \ No newline at end of file diff --git a/benchmark/ethereum/erc20/contract/ERC20.sol b/benchmark/ethereum/erc20/contract/ERC20.sol new file mode 100644 index 0000000..6fe8e80 --- /dev/null +++ b/benchmark/ethereum/erc20/contract/ERC20.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +interface IERC20 { + function totalSupply() external view returns (uint256); + + function balanceOf(address account) external view returns (uint256); + + function transfer(address recipient, uint256 amount) external returns (bool); + + function allowance(address owner, address spender) external view returns (uint256); + + function approve(address spender, uint256 amount) external returns (bool); + + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +contract ERC20 is IERC20 { + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + string public name = "Test Token on Axiom"; + string public symbol = "TAXM"; + uint8 public decimals = 9; + + function totalSupply() public view returns (uint256) { + return _totalSupply; + } + + function balanceOf(address account) public view returns (uint256) { + return _balances[account]; + } + + function transfer(address recipient, uint256 amount) public returns (bool) { + require(balanceOf(msg.sender) >= amount, "Insufficient balance"); + + _balances[msg.sender] -= amount; + _balances[recipient] += amount; + emit Transfer(msg.sender, recipient, amount); + return true; + } + + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; + } + + function approve(address spender, uint256 amount) external returns (bool) { + _allowances[msg.sender][spender] = amount; + emit Approval(msg.sender, spender, amount); + return true; + } + + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external returns (bool) { + require(allowance(sender, msg.sender) >= amount, "Insufficient allowance"); + require(balanceOf(sender) >= amount, "Insufficient balance"); + + _allowances[sender][msg.sender] -= amount; + + _balances[sender] -= amount; + _balances[recipient] += amount; + emit Transfer(sender, recipient, amount); + return true; + } + + function mint(uint256 amount) external { + _balances[msg.sender] += amount; + _totalSupply += amount; + emit Transfer(address(0), msg.sender, amount); + } + + function burn(uint256 amount) external { + _balances[msg.sender] -= amount; + _totalSupply -= amount; + emit Transfer(msg.sender, address(0), amount); + } +} \ No newline at end of file diff --git a/benchmark/ethereum/erc20/eth/eth.toml b/benchmark/ethereum/erc20/eth/eth.toml new file mode 100644 index 0000000..dcd9a3e --- /dev/null +++ b/benchmark/ethereum/erc20/eth/eth.toml @@ -0,0 +1,3 @@ +[rpc] +node = "http://172.16.30.85" +port = "7881" \ No newline at end of file diff --git a/benchmark/ethereum/erc20/script.lua b/benchmark/ethereum/erc20/script.lua new file mode 100755 index 0000000..7a9d7c9 --- /dev/null +++ b/benchmark/ethereum/erc20/script.lua @@ -0,0 +1,110 @@ +local case = testcase.new() + +function case:BeforeRun() + -- -- transfer token + -- local tokenAddrList = { + -- "f39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + -- "70997970C51812dc3A010C7d01b50e0d17dc79C8", + -- "3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + -- "90F79bf6EB2c4f870365E785982E1f101E93b906", + -- "15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + -- "9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + -- "976EA74026E726554dB657fA54763abd0C3a0aa9", + -- "14dC79964da2C08b23698B3D3cc7Ca32193d9955", + -- "23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f", + -- "a0Ee7A142d267C1f36714E4a8F75612F20a79720", + -- "Bcd4042DE499D14e55001CcbB24a551F3b954096", + -- "71bE63f3384f5fb98995898A86B02Fb2426c5788", + -- "FABB0ac9d68B0B445fB7357272Ff202C5651694a", + -- "1CBd3b2770909D4e10f157cABC84C7264073C9Ec", + -- "dF3e18d64BC6A983f673Ab319CCaE4f1a57C7097", + -- "cd3B766CCDd6AE721141F452C550Ca635964ce71", + -- "2546BcD3c84621e976D8185a91A922aE77ECEc30", + -- "bDA5747bFD65F08deb54cb465eB87D40e51B197E", + -- "dD2FD4581271e230360230F9337D5c0430Bf44C0", + -- "8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199", + -- } + -- local engineNum = self.index.Engine + -- local tokenLen = #tokenAddrList + -- if engineNum > tokenLen then + -- print("please set engine.cap num: " .. engineNum .. "smaller than token list length:" .. tokenLen .. " when call before run") + -- return + -- end + -- local accountNum = self.index.Accounts + -- local index = self.index.VM + -- --print("accounts num:" .. self.index.Accounts) + -- local from = tokenAddrList[index + 1] + -- local result + -- for i=13579,accountNum do + -- local toAddr = self.blockchain:GetAccount(i-1) + -- if toAddr ~= from then + -- result = self.blockchain:Transfer({ + -- from = from, + -- to = toAddr, + -- amount = 1000, + -- extra = "11", + -- }) + -- end + -- end + + -- -- wait token confirm + -- self.blockchain:Confirm(result) + + -- mint erc20 + -- for i=1,13579 do + -- local index = i % self.index.Engine + -- if index == self.index.VM then + -- local fromAddr = self.blockchain:GetAccount(i-1) + -- result = self.blockchain:Invoke({ + -- caller = fromAddr, + -- contract = "ERC20", -- contract name is the contract file name under directory invoke/contract + -- func = "mint", + -- args = {100000000}, + -- }) + -- end + -- end + + -- wait token confirm + --self.blockchain:Confirm(result) + + -- set contract address + --self.blockchain:SetContext('{"contract_name": "ERC20", "contract_addr": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E"}') +end + +function case:Run() + -- invoke erc20 contract + local fromAddr = self.blockchain:GetRandomAccountByGroup() + local toAddr = self.blockchain:GetRandomAccount(fromAddr) + --print("to addr:" .. toAddr) + local random = self.toolkit.RandInt(0, 2) + local value = self.toolkit.RandInt(1, 100) + local result + if random == 0 then + result = self.blockchain:Invoke({ + caller = fromAddr, + contract = "ERC20", + func = "transfer", + args = {toAddr, value}, + }) + else + result = self.blockchain:Invoke({ + caller = fromAddr, + contract = "ERC20", + func = "approve", + args = {toAddr, value}, + }) + + recvAddr = self.blockchain:GetRandomAccount(fromAddr) + result = self.blockchain:Invoke({ + caller = toAddr, + contract = "ERC20", + func = "transferFrom", + args = {fromAddr, recvAddr, value}, + }) + end + + --print("call result:" .. result.UID) + --self.blockchain:Confirm(result) + return result +end +return case \ No newline at end of file diff --git a/benchmark/ethereum/invoke/config.toml b/benchmark/ethereum/invoke/config.toml deleted file mode 100755 index 4e3c895..0000000 --- a/benchmark/ethereum/invoke/config.toml +++ /dev/null @@ -1,27 +0,0 @@ -[engine] -rate = 20 -duration = "20s" -cap = 4 - -[client] -script = "benchmark/ethereum/invoke/script.lua" # 脚本 -type = "eth" # 区块链类型 -contract = "benchmark/ethereum/invoke/contract" # 合约目录路径 -config = "benchmark/ethereum/invoke/eth" # 区块链SDK配置路径 -plugin = "./eth.so" # 插件路径 -args = ["1.0"] # 合约参数路径 - -[client.options] # 客户端选项 - -[recorder.log] -dump=false -dir="./logs" -level="debug" - -[recorder.csv] -dir="./csv" - - - - - diff --git a/benchmark/ethereum/invoke/contract/Store.sol b/benchmark/ethereum/invoke/contract/Store.sol deleted file mode 100755 index 10686ee..0000000 --- a/benchmark/ethereum/invoke/contract/Store.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity ^0.8.6; - -contract Store { - event ItemSet(string key, string value); - - string public version; - mapping (string => string) public items; - - constructor(string memory _version) public { - version = _version; - } - - function test(string memory key, string memory value) external { - items[key] = value; - emit ItemSet(key, value); - } -} \ No newline at end of file diff --git a/benchmark/ethereum/invoke/contract/Store_sol_Store.abi b/benchmark/ethereum/invoke/contract/Store_sol_Store.abi deleted file mode 100755 index a478e71..0000000 --- a/benchmark/ethereum/invoke/contract/Store_sol_Store.abi +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"string","name":"_version","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"key","type":"string"},{"indexed":false,"internalType":"string","name":"value","type":"string"}],"name":"ItemSet","type":"event"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"items","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"test","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/benchmark/ethereum/invoke/contract/Store_sol_Store.bin b/benchmark/ethereum/invoke/contract/Store_sol_Store.bin deleted file mode 100755 index f46e996..0000000 --- a/benchmark/ethereum/invoke/contract/Store_sol_Store.bin +++ /dev/null @@ -1 +0,0 @@ -60806040523480156200001157600080fd5b5060405162000a5738038062000a578339818101604052810190620000379190620002a4565b80600090805190602001906200004f92919062000057565b50506200035a565b828054620000659062000324565b90600052602060002090601f016020900481019282620000895760008555620000d5565b82601f10620000a457805160ff1916838001178555620000d5565b82800160010185558215620000d5579182015b82811115620000d4578251825591602001919060010190620000b7565b5b509050620000e49190620000e8565b5090565b5b8082111562000103576000816000905550600101620000e9565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620001708262000125565b810181811067ffffffffffffffff8211171562000192576200019162000136565b5b80604052505050565b6000620001a762000107565b9050620001b5828262000165565b919050565b600067ffffffffffffffff821115620001d857620001d762000136565b5b620001e38262000125565b9050602081019050919050565b60005b8381101562000210578082015181840152602081019050620001f3565b8381111562000220576000848401525b50505050565b60006200023d6200023784620001ba565b6200019b565b9050828152602081018484840111156200025c576200025b62000120565b5b62000269848285620001f0565b509392505050565b600082601f8301126200028957620002886200011b565b5b81516200029b84826020860162000226565b91505092915050565b600060208284031215620002bd57620002bc62000111565b5b600082015167ffffffffffffffff811115620002de57620002dd62000116565b5b620002ec8482850162000271565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200033d57607f821691505b60208210811415620003545762000353620002f5565b5b50919050565b6106ed806200036a6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634909b29b1461004657806354fd4d5014610076578063bab86ea814610094575b600080fd5b610060600480360381019061005b9190610461565b6100b0565b60405161006d9190610532565b60405180910390f35b61007e610166565b60405161008b9190610532565b60405180910390f35b6100ae60048036038101906100a99190610554565b6101f4565b005b60018180516020810182018051848252602083016020850120818352809550505050505060009150905080546100e5906105fb565b80601f0160208091040260200160405190810160405280929190818152602001828054610111906105fb565b801561015e5780601f106101335761010080835404028352916020019161015e565b820191906000526020600020905b81548152906001019060200180831161014157829003601f168201915b505050505081565b60008054610173906105fb565b80601f016020809104026020016040519081016040528092919081815260200182805461019f906105fb565b80156101ec5780601f106101c1576101008083540402835291602001916101ec565b820191906000526020600020905b8154815290600101906020018083116101cf57829003601f168201915b505050505081565b806001836040516102059190610669565b90815260200160405180910390209080519060200190610226929190610264565b507f523139e7aa4a7267d8d1b859cba73a73993683d42bc00a7a06770e7b6ca57ef38282604051610258929190610680565b60405180910390a15050565b828054610270906105fb565b90600052602060002090601f01602090048101928261029257600085556102d9565b82601f106102ab57805160ff19168380011785556102d9565b828001600101855582156102d9579182015b828111156102d85782518255916020019190600101906102bd565b5b5090506102e691906102ea565b5090565b5b808211156103035760008160009055506001016102eb565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61036e82610325565b810181811067ffffffffffffffff8211171561038d5761038c610336565b5b80604052505050565b60006103a0610307565b90506103ac8282610365565b919050565b600067ffffffffffffffff8211156103cc576103cb610336565b5b6103d582610325565b9050602081019050919050565b82818337600083830152505050565b60006104046103ff846103b1565b610396565b9050828152602081018484840111156104205761041f610320565b5b61042b8482856103e2565b509392505050565b600082601f8301126104485761044761031b565b5b81356104588482602086016103f1565b91505092915050565b60006020828403121561047757610476610311565b5b600082013567ffffffffffffffff81111561049557610494610316565b5b6104a184828501610433565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156104e45780820151818401526020810190506104c9565b838111156104f3576000848401525b50505050565b6000610504826104aa565b61050e81856104b5565b935061051e8185602086016104c6565b61052781610325565b840191505092915050565b6000602082019050818103600083015261054c81846104f9565b905092915050565b6000806040838503121561056b5761056a610311565b5b600083013567ffffffffffffffff81111561058957610588610316565b5b61059585828601610433565b925050602083013567ffffffffffffffff8111156105b6576105b5610316565b5b6105c285828601610433565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061061357607f821691505b60208210811415610627576106266105cc565b5b50919050565b600081905092915050565b6000610643826104aa565b61064d818561062d565b935061065d8185602086016104c6565b80840191505092915050565b60006106758284610638565b915081905092915050565b6000604082019050818103600083015261069a81856104f9565b905081810360208301526106ae81846104f9565b9050939250505056fea264697066735822122024a8f62b1431c4dd659db0ffe1e00339bda0fb6df1070b8ecc2199ac89b5601a64736f6c63430008090033 \ No newline at end of file diff --git a/benchmark/ethereum/invoke/eth/eth.toml b/benchmark/ethereum/invoke/eth/eth.toml deleted file mode 100644 index 98cca05..0000000 --- a/benchmark/ethereum/invoke/eth/eth.toml +++ /dev/null @@ -1,3 +0,0 @@ -[rpc] -node = "http://localhost" -port = "8545" \ No newline at end of file diff --git a/benchmark/ethereum/invoke/eth/keystore/UTC--2021-11-08T06-39-32.219546000Z--74d366e0649a91395bb122c005917644382b9452 b/benchmark/ethereum/invoke/eth/keystore/UTC--2021-11-08T06-39-32.219546000Z--74d366e0649a91395bb122c005917644382b9452 deleted file mode 100644 index 84b4241..0000000 --- a/benchmark/ethereum/invoke/eth/keystore/UTC--2021-11-08T06-39-32.219546000Z--74d366e0649a91395bb122c005917644382b9452 +++ /dev/null @@ -1 +0,0 @@ -{"address":"74d366e0649a91395bb122c005917644382b9452","crypto":{"cipher":"aes-128-ctr","ciphertext":"fc4e8e2c753a98762828fad76697322da6a0143d6bfe223ce8a590637b433b75","cipherparams":{"iv":"9eab2eb01311d078ac7e3325150eecb2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0a8bda7b2e61a563a277601e65f6f30a92ab58e6e18f806105bb7218dff4c883"},"mac":"18f543410e2869a6a843166f1c3fb6aae5a5ec0dc6fdd41d1d76d8e8b19c5983"},"id":"98123f84-3855-4f12-b844-8c0d8ac02c09","version":3} \ No newline at end of file diff --git a/benchmark/ethereum/invoke/eth/keystore/UTC--2021-11-08T06-40-13.429398000Z--3b2b643246666bfa1332257c13d0d1283736838d b/benchmark/ethereum/invoke/eth/keystore/UTC--2021-11-08T06-40-13.429398000Z--3b2b643246666bfa1332257c13d0d1283736838d deleted file mode 100644 index aefe4b2..0000000 --- a/benchmark/ethereum/invoke/eth/keystore/UTC--2021-11-08T06-40-13.429398000Z--3b2b643246666bfa1332257c13d0d1283736838d +++ /dev/null @@ -1 +0,0 @@ -{"address":"3b2b643246666bfa1332257c13d0d1283736838d","crypto":{"cipher":"aes-128-ctr","ciphertext":"50b10e30295ff3a5b729b3bc62e89145ebf6b5839cd3b8c13dcbbf099584cec6","cipherparams":{"iv":"fe3dd61296891e6654fd1b39ff2401a2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"1244ce8b522ff776be571c8814a7dfd6c8607aecd1f3b145385a27aa0d1443c7"},"mac":"78ff225aa55470d242b1464b9b42476313024bbfab343a5bbd27e748c67b44d8"},"id":"c066e226-9b72-4d63-a556-70034d0a135b","version":3} \ No newline at end of file diff --git a/benchmark/ethereum/invoke/script.lua b/benchmark/ethereum/invoke/script.lua deleted file mode 100755 index 48a7292..0000000 --- a/benchmark/ethereum/invoke/script.lua +++ /dev/null @@ -1,10 +0,0 @@ -local case = testcase.new() -function case:Run() - local result = self.blockchain:Invoke({ - func = "test", - args = {"foo","bar"}, - }) - self.blockchain:Confirm(result) - return result -end -return case \ No newline at end of file diff --git a/benchmark/ethereum/transfer/config.toml b/benchmark/ethereum/transfer/config.toml index 2d98004..0d7879c 100755 --- a/benchmark/ethereum/transfer/config.toml +++ b/benchmark/ethereum/transfer/config.toml @@ -1,7 +1,8 @@ [engine] -rate = 20 -duration = "20s" -cap = 3 +rate = 10 +duration = "10s" +cap = 20 +accounts = 1000 [client] script = "benchmark/ethereum/transfer/script.lua" # 脚本 @@ -14,7 +15,7 @@ plugin = "./eth.so" # 插件路径 [recorder.log] dump=false dir="./logs" -level="debug" +level="info" [recorder.csv] dir="./csv" diff --git a/benchmark/ethereum/transfer/eth/eth.toml b/benchmark/ethereum/transfer/eth/eth.toml index e1dedb5..79e830a 100644 --- a/benchmark/ethereum/transfer/eth/eth.toml +++ b/benchmark/ethereum/transfer/eth/eth.toml @@ -1,3 +1,3 @@ [rpc] -node = "ws://localhost" -port = "8546" \ No newline at end of file +node = "ws://172.16.13.131" +port = "9091" \ No newline at end of file diff --git a/benchmark/ethereum/transfer/eth/keystore/UTC--2021-11-08T06-39-32.219546000Z--74d366e0649a91395bb122c005917644382b9452 b/benchmark/ethereum/transfer/eth/keystore/UTC--2021-11-08T06-39-32.219546000Z--74d366e0649a91395bb122c005917644382b9452 deleted file mode 100644 index 84b4241..0000000 --- a/benchmark/ethereum/transfer/eth/keystore/UTC--2021-11-08T06-39-32.219546000Z--74d366e0649a91395bb122c005917644382b9452 +++ /dev/null @@ -1 +0,0 @@ -{"address":"74d366e0649a91395bb122c005917644382b9452","crypto":{"cipher":"aes-128-ctr","ciphertext":"fc4e8e2c753a98762828fad76697322da6a0143d6bfe223ce8a590637b433b75","cipherparams":{"iv":"9eab2eb01311d078ac7e3325150eecb2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0a8bda7b2e61a563a277601e65f6f30a92ab58e6e18f806105bb7218dff4c883"},"mac":"18f543410e2869a6a843166f1c3fb6aae5a5ec0dc6fdd41d1d76d8e8b19c5983"},"id":"98123f84-3855-4f12-b844-8c0d8ac02c09","version":3} \ No newline at end of file diff --git a/benchmark/ethereum/transfer/eth/keystore/UTC--2021-11-08T06-40-13.429398000Z--3b2b643246666bfa1332257c13d0d1283736838d b/benchmark/ethereum/transfer/eth/keystore/UTC--2021-11-08T06-40-13.429398000Z--3b2b643246666bfa1332257c13d0d1283736838d deleted file mode 100644 index aefe4b2..0000000 --- a/benchmark/ethereum/transfer/eth/keystore/UTC--2021-11-08T06-40-13.429398000Z--3b2b643246666bfa1332257c13d0d1283736838d +++ /dev/null @@ -1 +0,0 @@ -{"address":"3b2b643246666bfa1332257c13d0d1283736838d","crypto":{"cipher":"aes-128-ctr","ciphertext":"50b10e30295ff3a5b729b3bc62e89145ebf6b5839cd3b8c13dcbbf099584cec6","cipherparams":{"iv":"fe3dd61296891e6654fd1b39ff2401a2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"1244ce8b522ff776be571c8814a7dfd6c8607aecd1f3b145385a27aa0d1443c7"},"mac":"78ff225aa55470d242b1464b9b42476313024bbfab343a5bbd27e748c67b44d8"},"id":"c066e226-9b72-4d63-a556-70034d0a135b","version":3} \ No newline at end of file diff --git a/benchmark/ethereum/transfer/script.lua b/benchmark/ethereum/transfer/script.lua index 18a0f1b..70401c2 100755 --- a/benchmark/ethereum/transfer/script.lua +++ b/benchmark/ethereum/transfer/script.lua @@ -1,12 +1,73 @@ local case = testcase.new() + +function sleep(n) + os.execute("sleep " .. tonumber(n)) +end + +function case:BeforeRun() + -- transfer token + local tokenAddrList = { + "f39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "70997970C51812dc3A010C7d01b50e0d17dc79C8", + "3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "90F79bf6EB2c4f870365E785982E1f101E93b906", + "15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + "9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "976EA74026E726554dB657fA54763abd0C3a0aa9", + "14dC79964da2C08b23698B3D3cc7Ca32193d9955", + "23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f", + "a0Ee7A142d267C1f36714E4a8F75612F20a79720", + "Bcd4042DE499D14e55001CcbB24a551F3b954096", + "71bE63f3384f5fb98995898A86B02Fb2426c5788", + "FABB0ac9d68B0B445fB7357272Ff202C5651694a", + "1CBd3b2770909D4e10f157cABC84C7264073C9Ec", + "dF3e18d64BC6A983f673Ab319CCaE4f1a57C7097", + "cd3B766CCDd6AE721141F452C550Ca635964ce71", + "2546BcD3c84621e976D8185a91A922aE77ECEc30", + "bDA5747bFD65F08deb54cb465eB87D40e51B197E", + "dD2FD4581271e230360230F9337D5c0430Bf44C0", + "8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199", + } + local engineNum = self.index.Engine + local tokenLen = #tokenAddrList + if engineNum > tokenLen then + print("please set engine.cap num: " .. engineNum .. "smaller than token list length:" .. tokenLen .. " when call before run") + return + end + local accountNum = self.index.Accounts + local index = self.index.VM + --print("accounts num:" .. self.index.Accounts) + local from = tokenAddrList[index + 1] + local result + for i=1,accountNum do + local toAddr = self.blockchain:GetAccount(i-1) + if toAddr ~= from then + result = self.blockchain:Transfer({ + from = from, + to = toAddr, + amount = 1000, + extra = "11", + }) + end + end + + -- wait token confirm + self.blockchain:Confirm(result) +end + function case:Run() - local ret = case.blockchain:Transfer({ - from = "74d366e0649a91395bb122c005917644382b9452", - to = "3b2b643246666bfa1332257c13d0d1283736838d", - amount = 100, + --print("----start lua vm-----") + fromAddr = self.blockchain:GetRandomAccountByGroup() + toAddr = self.blockchain:GetRandomAccount(fromAddr) + --print("from addr:" .. fromAddr .. "to addr:" .. toAddr) + value = self.toolkit.RandInt(1, 100) + local ret = self.blockchain:Transfer({ + from = fromAddr, --"14dC79964da2C08b23698B3D3cc7Ca32193d9955", + to = toAddr, --"90f79bf6eb2c4f870365e785982e1f101e93b906", + amount = value * 0.01, extra = "11", }) - self.blockchain:Confirm(ret) + --print(ret) return ret end diff --git a/benchmark/ethereum/uniswap/config.toml b/benchmark/ethereum/uniswap/config.toml new file mode 100755 index 0000000..93104c3 --- /dev/null +++ b/benchmark/ethereum/uniswap/config.toml @@ -0,0 +1,30 @@ +[engine] +rate = 1 # 速率,重点压测指标 +duration = "10s" # 持续时间 +cap = 2 # 客户端虚拟机数量,类似CPU核心数 +accounts = 1000 # 总账户数 + +# uniswap 稳定性测试配置 +[client] +script = "benchmark/ethereum/uniswap/script.lua" # 脚本 +type = "eth" # 区块链类型 +contract = "benchmark/ethereum/uniswap/contract" # 合约目录 +contract_num = 1 # 合约部署数量 +config = "benchmark/ethereum/uniswap/eth" # 区块链SDK配置路径 +plugin = "./eth.so" # 插件路径 +args = [] + +[client.options] # 客户端选项 + +[recorder.log] +dump=false +dir="./logs" +level="debug" + +[recorder.csv] +dir="./csv" + + + + + diff --git a/benchmark/ethereum/uniswap/contract/Token1.abi b/benchmark/ethereum/uniswap/contract/Token1.abi new file mode 100644 index 0000000..51c898c --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token1.abi @@ -0,0 +1,313 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token1.bin b/benchmark/ethereum/uniswap/contract/Token1.bin new file mode 100644 index 0000000..a0a2c1c --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token1.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b5060405180604001604052806006815260200165546f6b656e3160d01b81525060405180604001604052806003815260200162544b3160e81b81525081600390816200005e91906200011b565b5060046200006d82826200011b565b505050620001e7565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000a157607f821691505b602082108103620000c257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200011657600081815260208120601f850160051c81016020861015620000f15750805b601f850160051c820191505b818110156200011257828155600101620000fd565b5050505b505050565b81516001600160401b0381111562000137576200013762000076565b6200014f816200014884546200008c565b84620000c8565b602080601f8311600181146200018757600084156200016e5750858301515b600019600386901b1c1916600185901b17855562000112565b600085815260208120601f198616915b82811015620001b85788860151825594840194600190910190840162000197565b5085821015620001d75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610aa280620001f76000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c5780639dc29fac116100665780639dc29fac146101a2578063a457c2d7146101b5578063a9059cbb146101c8578063dd62ed3e146101db57600080fd5b806340c10f191461015c57806370a082311461017157806395d89b411461019a57600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd14610127578063313ce5671461013a5780633950935114610149575b600080fd5b6100dc6101ee565b6040516100e991906108ec565b60405180910390f35b610105610100366004610956565b610280565b60405190151581526020016100e9565b6002545b6040519081526020016100e9565b610105610135366004610980565b61029a565b604051601281526020016100e9565b610105610157366004610956565b6102be565b61016f61016a366004610956565b6102e0565b005b61011961017f3660046109bc565b6001600160a01b031660009081526020819052604090205490565b6100dc6102ee565b61016f6101b0366004610956565b6102fd565b6101056101c3366004610956565b610307565b6101056101d6366004610956565b610387565b6101196101e93660046109de565b610395565b6060600380546101fd90610a11565b80601f016020809104026020016040519081016040528092919081815260200182805461022990610a11565b80156102765780601f1061024b57610100808354040283529160200191610276565b820191906000526020600020905b81548152906001019060200180831161025957829003601f168201915b5050505050905090565b60003361028e8185856103c0565b60019150505b92915050565b6000336102a88582856104e5565b6102b385858561055f565b506001949350505050565b60003361028e8185856102d18383610395565b6102db9190610a4b565b6103c0565b6102ea8282610703565b5050565b6060600480546101fd90610a11565b6102ea82826107c2565b600033816103158286610395565b90508381101561037a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6102b382868684036103c0565b60003361028e81858561055f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166104225760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610371565b6001600160a01b0382166104835760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610371565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006104f18484610395565b90506000198114610559578181101561054c5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610371565b61055984848484036103c0565b50505050565b6001600160a01b0383166105c35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610371565b6001600160a01b0382166106255760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610371565b6001600160a01b0383166000908152602081905260409020548181101561069d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610371565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610559565b6001600160a01b0382166107595760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610371565b806002600082825461076b9190610a4b565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166108225760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610371565b6001600160a01b038216600090815260208190526040902054818110156108965760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610371565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016104d8565b600060208083528351808285015260005b81811015610919578581018301518582016040015282016108fd565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461095157600080fd5b919050565b6000806040838503121561096957600080fd5b6109728361093a565b946020939093013593505050565b60008060006060848603121561099557600080fd5b61099e8461093a565b92506109ac6020850161093a565b9150604084013590509250925092565b6000602082840312156109ce57600080fd5b6109d78261093a565b9392505050565b600080604083850312156109f157600080fd5b6109fa8361093a565b9150610a086020840161093a565b90509250929050565b600181811c90821680610a2557607f821691505b602082108103610a4557634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561029457634e487b7160e01b600052601160045260246000fdfea2646970667358221220128f3a2a22cab9b7f8f76cbd1165619bad628a647041a7fe322de07bd216e2ec64736f6c63430008140033 \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token1.sol b/benchmark/ethereum/uniswap/contract/Token1.sol new file mode 100644 index 0000000..af30927 --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token1.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract Token1 is ERC20 { + constructor() ERC20("Token1", "TK1") { + } + + // 铸造代币 + function mint(address recipient, uint256 amount) public { + _mint(recipient, amount); + } + + // 销毁代币 + function burn(address from, uint256 amount) public { + _burn(from, amount); + } +} \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token2.abi b/benchmark/ethereum/uniswap/contract/Token2.abi new file mode 100644 index 0000000..51c898c --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token2.abi @@ -0,0 +1,313 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token2.bin b/benchmark/ethereum/uniswap/contract/Token2.bin new file mode 100644 index 0000000..375081c --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token2.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b50604051806040016040528060068152602001652a37b5b2b71960d11b815250604051806040016040528060038152602001622a259960e91b81525081600390816200005e91906200011b565b5060046200006d82826200011b565b505050620001e7565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000a157607f821691505b602082108103620000c257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200011657600081815260208120601f850160051c81016020861015620000f15750805b601f850160051c820191505b818110156200011257828155600101620000fd565b5050505b505050565b81516001600160401b0381111562000137576200013762000076565b6200014f816200014884546200008c565b84620000c8565b602080601f8311600181146200018757600084156200016e5750858301515b600019600386901b1c1916600185901b17855562000112565b600085815260208120601f198616915b82811015620001b85788860151825594840194600190910190840162000197565b5085821015620001d75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610aa280620001f76000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c5780639dc29fac116100665780639dc29fac146101a2578063a457c2d7146101b5578063a9059cbb146101c8578063dd62ed3e146101db57600080fd5b806340c10f191461015c57806370a082311461017157806395d89b411461019a57600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd14610127578063313ce5671461013a5780633950935114610149575b600080fd5b6100dc6101ee565b6040516100e991906108ec565b60405180910390f35b610105610100366004610956565b610280565b60405190151581526020016100e9565b6002545b6040519081526020016100e9565b610105610135366004610980565b61029a565b604051601281526020016100e9565b610105610157366004610956565b6102be565b61016f61016a366004610956565b6102e0565b005b61011961017f3660046109bc565b6001600160a01b031660009081526020819052604090205490565b6100dc6102ee565b61016f6101b0366004610956565b6102fd565b6101056101c3366004610956565b610307565b6101056101d6366004610956565b610387565b6101196101e93660046109de565b610395565b6060600380546101fd90610a11565b80601f016020809104026020016040519081016040528092919081815260200182805461022990610a11565b80156102765780601f1061024b57610100808354040283529160200191610276565b820191906000526020600020905b81548152906001019060200180831161025957829003601f168201915b5050505050905090565b60003361028e8185856103c0565b60019150505b92915050565b6000336102a88582856104e5565b6102b385858561055f565b506001949350505050565b60003361028e8185856102d18383610395565b6102db9190610a4b565b6103c0565b6102ea8282610703565b5050565b6060600480546101fd90610a11565b6102ea82826107c2565b600033816103158286610395565b90508381101561037a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6102b382868684036103c0565b60003361028e81858561055f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166104225760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610371565b6001600160a01b0382166104835760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610371565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006104f18484610395565b90506000198114610559578181101561054c5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610371565b61055984848484036103c0565b50505050565b6001600160a01b0383166105c35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610371565b6001600160a01b0382166106255760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610371565b6001600160a01b0383166000908152602081905260409020548181101561069d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610371565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610559565b6001600160a01b0382166107595760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610371565b806002600082825461076b9190610a4b565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166108225760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610371565b6001600160a01b038216600090815260208190526040902054818110156108965760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610371565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016104d8565b600060208083528351808285015260005b81811015610919578581018301518582016040015282016108fd565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461095157600080fd5b919050565b6000806040838503121561096957600080fd5b6109728361093a565b946020939093013593505050565b60008060006060848603121561099557600080fd5b61099e8461093a565b92506109ac6020850161093a565b9150604084013590509250925092565b6000602082840312156109ce57600080fd5b6109d78261093a565b9392505050565b600080604083850312156109f157600080fd5b6109fa8361093a565b9150610a086020840161093a565b90509250929050565b600181811c90821680610a2557607f821691505b602082108103610a4557634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561029457634e487b7160e01b600052601160045260246000fdfea2646970667358221220561b372ab1233ed49725058b04535614289e24b3ccaad7aba445a8ab2b990f0264736f6c63430008140033 \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token2.sol b/benchmark/ethereum/uniswap/contract/Token2.sol new file mode 100644 index 0000000..6b8370a --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token2.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract Token2 is ERC20 { + constructor() ERC20("Token2", "TK2") { + } + + // 铸造代币 + function mint(address recipient, uint256 amount) public { + _mint(recipient, amount); + } + + // 销毁代币 + function burn(address from, uint256 amount) public { + _burn(from, amount); + } +} \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token3.abi b/benchmark/ethereum/uniswap/contract/Token3.abi new file mode 100644 index 0000000..51c898c --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token3.abi @@ -0,0 +1,313 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token3.bin b/benchmark/ethereum/uniswap/contract/Token3.bin new file mode 100644 index 0000000..a8719ba --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token3.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b5060405180604001604052806006815260200165546f6b656e3360d01b81525060405180604001604052806003815260200162544b3360e81b81525081600390816200005e91906200011b565b5060046200006d82826200011b565b505050620001e7565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000a157607f821691505b602082108103620000c257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200011657600081815260208120601f850160051c81016020861015620000f15750805b601f850160051c820191505b818110156200011257828155600101620000fd565b5050505b505050565b81516001600160401b0381111562000137576200013762000076565b6200014f816200014884546200008c565b84620000c8565b602080601f8311600181146200018757600084156200016e5750858301515b600019600386901b1c1916600185901b17855562000112565b600085815260208120601f198616915b82811015620001b85788860151825594840194600190910190840162000197565b5085821015620001d75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610aa280620001f76000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c5780639dc29fac116100665780639dc29fac146101a2578063a457c2d7146101b5578063a9059cbb146101c8578063dd62ed3e146101db57600080fd5b806340c10f191461015c57806370a082311461017157806395d89b411461019a57600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd14610127578063313ce5671461013a5780633950935114610149575b600080fd5b6100dc6101ee565b6040516100e991906108ec565b60405180910390f35b610105610100366004610956565b610280565b60405190151581526020016100e9565b6002545b6040519081526020016100e9565b610105610135366004610980565b61029a565b604051601281526020016100e9565b610105610157366004610956565b6102be565b61016f61016a366004610956565b6102e0565b005b61011961017f3660046109bc565b6001600160a01b031660009081526020819052604090205490565b6100dc6102ee565b61016f6101b0366004610956565b6102fd565b6101056101c3366004610956565b610307565b6101056101d6366004610956565b610387565b6101196101e93660046109de565b610395565b6060600380546101fd90610a11565b80601f016020809104026020016040519081016040528092919081815260200182805461022990610a11565b80156102765780601f1061024b57610100808354040283529160200191610276565b820191906000526020600020905b81548152906001019060200180831161025957829003601f168201915b5050505050905090565b60003361028e8185856103c0565b60019150505b92915050565b6000336102a88582856104e5565b6102b385858561055f565b506001949350505050565b60003361028e8185856102d18383610395565b6102db9190610a4b565b6103c0565b6102ea8282610703565b5050565b6060600480546101fd90610a11565b6102ea82826107c2565b600033816103158286610395565b90508381101561037a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6102b382868684036103c0565b60003361028e81858561055f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166104225760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610371565b6001600160a01b0382166104835760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610371565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006104f18484610395565b90506000198114610559578181101561054c5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610371565b61055984848484036103c0565b50505050565b6001600160a01b0383166105c35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610371565b6001600160a01b0382166106255760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610371565b6001600160a01b0383166000908152602081905260409020548181101561069d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610371565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610559565b6001600160a01b0382166107595760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610371565b806002600082825461076b9190610a4b565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166108225760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610371565b6001600160a01b038216600090815260208190526040902054818110156108965760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610371565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016104d8565b600060208083528351808285015260005b81811015610919578581018301518582016040015282016108fd565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461095157600080fd5b919050565b6000806040838503121561096957600080fd5b6109728361093a565b946020939093013593505050565b60008060006060848603121561099557600080fd5b61099e8461093a565b92506109ac6020850161093a565b9150604084013590509250925092565b6000602082840312156109ce57600080fd5b6109d78261093a565b9392505050565b600080604083850312156109f157600080fd5b6109fa8361093a565b9150610a086020840161093a565b90509250929050565b600181811c90821680610a2557607f821691505b602082108103610a4557634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561029457634e487b7160e01b600052601160045260246000fdfea26469706673582212206d41a741c41ba8f52ff6859e770bbd32b585f18e5dc45e9ee22f5d186b47e9cc64736f6c63430008140033 \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/Token3.sol b/benchmark/ethereum/uniswap/contract/Token3.sol new file mode 100644 index 0000000..5deae1a --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/Token3.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract Token3 is ERC20 { + constructor() ERC20("Token3", "TK3") { + } + + // 铸造代币 + function mint(address recipient, uint256 amount) public { + _mint(recipient, amount); + } + + // 销毁代币 + function burn(address from, uint256 amount) public { + _burn(from, amount); + } +} \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/UniswapV2Router02.abi b/benchmark/ethereum/uniswap/contract/UniswapV2Router02.abi new file mode 100644 index 0000000..f126e58 --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/UniswapV2Router02.abi @@ -0,0 +1,962 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountADesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountTokenDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsIn", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsOut", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETHSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapETHForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/UniswapV2Router02.bin b/benchmark/ethereum/uniswap/contract/UniswapV2Router02.bin new file mode 100644 index 0000000..849d250 --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/UniswapV2Router02.bin @@ -0,0 +1 @@ +60c060405234801561001057600080fd5b507f10fdfb83fb801e4bb80219411e9ec437aec1e1050000000000000000000000006080527f5aea6ea637074b48fdfb32ad9291009e03d0cb2d00000000000000000000000060a0527310fdfb83fb801e4bb80219411e9ec437aec1e105735aea6ea637074b48fdfb32ad9291009e03d0cb2d6146986101a46000398061019f5280610d245280610d5f5280610e56528061107452806113fe5280611564528061192b5280611a255280611adb5280611ba95280611cef5280611d775280611fbc528061203752806120e652806121b2528061224752806122bb52806127b95280612a2c5280612a825280612ab65280612b2a5280612cca5280612e0d5280612e95525080610ee45280610fbb528061113a528061117352806112ae528061148c528061154252806116b25280611c3c5280611da95280611f0c52806122ed5280612546528061273e5280612767528061279752806129045280612a605280612d5d5280612ec7528061377052806137b35280613a965280613c1c52806140545280614102528061418252506146986000f3fe60806040526004361061018f5760003560e01c80638803dbee116100d6578063c45a01551161007f578063e8e3370011610059578063e8e3370014610b8d578063f305d71914610c0d578063fb3bdb4114610c53576101c8565b8063c45a015514610a50578063d06ca61f14610a65578063ded9382a14610b1a576101c8565b8063af2979eb116100b0578063af2979eb1461091c578063b6f9de951461096f578063baa2abde146109f3576101c8565b80638803dbee1461081f578063ad5c4648146108b5578063ad615dec146108e6576101c8565b80634a25d94a11610138578063791ac94711610112578063791ac947146106cf5780637ff36ab51461076557806385f8c259146107e9576101c8565b80634a25d94a146105305780635b0d5984146105c65780635c11d79514610639576101c8565b80631f00ca74116101695780631f00ca74146103675780632195995c1461041c57806338ed17391461049a576101c8565b806302751cec146101cd578063054d50d41461023957806318cbafe514610281576101c8565b366101c857336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101c657fe5b005b600080fd5b3480156101d957600080fd5b50610220600480360360c08110156101f057600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135610cd7565b6040805192835260208301919091528051918290030190f35b34801561024557600080fd5b5061026f6004803603606081101561025c57600080fd5b5080359060208101359060400135610df1565b60408051918252519081900360200190f35b34801561028d57600080fd5b50610317600480360360a08110156102a457600080fd5b813591602081013591810190606081016040820135600160201b8111156102ca57600080fd5b8201836020820111156102dc57600080fd5b803590602001918460208302840111600160201b831117156102fd57600080fd5b91935091506001600160a01b038135169060200135610e06565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561035357818101518382015260200161033b565b505050509050019250505060405180910390f35b34801561037357600080fd5b506103176004803603604081101561038a57600080fd5b81359190810190604081016020820135600160201b8111156103ab57600080fd5b8201836020820111156103bd57600080fd5b803590602001918460208302840111600160201b831117156103de57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611133945050505050565b34801561042857600080fd5b50610220600480360361016081101561044057600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c08101359060e081013515159060ff6101008201351690610120810135906101400135611169565b3480156104a657600080fd5b50610317600480360360a08110156104bd57600080fd5b813591602081013591810190606081016040820135600160201b8111156104e357600080fd5b8201836020820111156104f557600080fd5b803590602001918460208302840111600160201b8311171561051657600080fd5b91935091506001600160a01b038135169060200135611263565b34801561053c57600080fd5b50610317600480360360a081101561055357600080fd5b813591602081013591810190606081016040820135600160201b81111561057957600080fd5b82018360208201111561058b57600080fd5b803590602001918460208302840111600160201b831117156105ac57600080fd5b91935091506001600160a01b0381351690602001356113ae565b3480156105d257600080fd5b5061026f60048036036101408110156105ea57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e0820135169061010081013590610120013561153a565b34801561064557600080fd5b506101c6600480360360a081101561065c57600080fd5b813591602081013591810190606081016040820135600160201b81111561068257600080fd5b82018360208201111561069457600080fd5b803590602001918460208302840111600160201b831117156106b557600080fd5b91935091506001600160a01b038135169060200135611648565b3480156106db57600080fd5b506101c6600480360360a08110156106f257600080fd5b813591602081013591810190606081016040820135600160201b81111561071857600080fd5b82018360208201111561072a57600080fd5b803590602001918460208302840111600160201b8311171561074b57600080fd5b91935091506001600160a01b0381351690602001356118dd565b6103176004803603608081101561077b57600080fd5b81359190810190604081016020820135600160201b81111561079c57600080fd5b8201836020820111156107ae57600080fd5b803590602001918460208302840111600160201b831117156107cf57600080fd5b91935091506001600160a01b038135169060200135611b61565b3480156107f557600080fd5b5061026f6004803603606081101561080c57600080fd5b5080359060208101359060400135611eb4565b34801561082b57600080fd5b50610317600480360360a081101561084257600080fd5b813591602081013591810190606081016040820135600160201b81111561086857600080fd5b82018360208201111561087a57600080fd5b803590602001918460208302840111600160201b8311171561089b57600080fd5b91935091506001600160a01b038135169060200135611ec1565b3480156108c157600080fd5b506108ca611fba565b604080516001600160a01b039092168252519081900360200190f35b3480156108f257600080fd5b5061026f6004803603606081101561090957600080fd5b5080359060208101359060400135611fde565b34801561092857600080fd5b5061026f600480360360c081101561093f57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135611feb565b6101c66004803603608081101561098557600080fd5b81359190810190604081016020820135600160201b8111156109a657600080fd5b8201836020820111156109b857600080fd5b803590602001918460208302840111600160201b831117156109d957600080fd5b91935091506001600160a01b03813516906020013561216c565b3480156109ff57600080fd5b50610220600480360360e0811015610a1657600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c001356124f8565b348015610a5c57600080fd5b506108ca61273c565b348015610a7157600080fd5b5061031760048036036040811015610a8857600080fd5b81359190810190604081016020820135600160201b811115610aa957600080fd5b820183602082011115610abb57600080fd5b803590602001918460208302840111600160201b83111715610adc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612760945050505050565b348015610b2657600080fd5b506102206004803603610140811015610b3e57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e0820135169061010081013590610120013561278d565b348015610b9957600080fd5b50610bef6004803603610100811015610bb157600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c0820135169060e001356128a1565b60408051938452602084019290925282820152519081900360600190f35b610bef600480360360c0811015610c2357600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a001356129dd565b61031760048036036080811015610c6957600080fd5b81359190810190604081016020820135600160201b811115610c8a57600080fd5b820183602082011115610c9c57600080fd5b803590602001918460208302840111600160201b83111715610cbd57600080fd5b91935091506001600160a01b038135169060200135612c82565b6000808242811015610d1e576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b610d4d897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a6124f8565b9093509150610d5d898685613004565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b50505050610de58583613158565b50965096945050505050565b6000610dfe848484613250565b949350505050565b60608142811015610e4c576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686866000198101818110610e8657fe5b905060200201356001600160a01b03166001600160a01b031614610edf576040805162461bcd60e51b815260206004820152601d602482015260008051602061457a833981519152604482015290519081900360640190fd5b610f3d7f00000000000000000000000000000000000000000000000000000000000000008988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061334092505050565b91508682600184510381518110610f5057fe5b60200260200101511015610f955760405162461bcd60e51b815260040180806020018281038252602b8152602001806145c0602b913960400191505060405180910390fd5b61103386866000818110610fa557fe5b905060200201356001600160a01b0316336110197f00000000000000000000000000000000000000000000000000000000000000008a8a6000818110610fe757fe5b905060200201356001600160a01b03168b8b600181811061100457fe5b905060200201356001600160a01b031661348c565b8560008151811061102657fe5b6020026020010151613564565b611072828787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152503092506136c1915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836001855103815181106110b157fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156110ef57600080fd5b505af1158015611103573d6000803e3d6000fd5b50505050611128848360018551038151811061111b57fe5b6020026020010151613158565b509695505050505050565b60606111607f00000000000000000000000000000000000000000000000000000000000000008484613907565b90505b92915050565b60008060006111997f00000000000000000000000000000000000000000000000000000000000000008f8f61348c565b90506000876111a8578c6111ac565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561122257600080fd5b505af1158015611236573d6000803e3d6000fd5b505050506112498f8f8f8f8f8f8f6124f8565b809450819550505050509b509b9950505050505050505050565b606081428110156112a9576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b6113077f00000000000000000000000000000000000000000000000000000000000000008988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061334092505050565b9150868260018451038151811061131a57fe5b6020026020010151101561135f5760405162461bcd60e51b815260040180806020018281038252602b8152602001806145c0602b913960400191505060405180910390fd5b61136f86866000818110610fa557fe5b611128828787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508992506136c1915050565b606081428110156113f4576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686600019810181811061142e57fe5b905060200201356001600160a01b03166001600160a01b031614611487576040805162461bcd60e51b815260206004820152601d602482015260008051602061457a833981519152604482015290519081900360640190fd5b6114e57f00000000000000000000000000000000000000000000000000000000000000008988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061390792505050565b915086826000815181106114f557fe5b60200260200101511115610f955760405162461bcd60e51b81526004018080602001828103825260278152602001806145536027913960400191505060405180910390fd5b6000806115887f00000000000000000000000000000000000000000000000000000000000000008d7f000000000000000000000000000000000000000000000000000000000000000061348c565b9050600086611597578b61159b565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018b905260ff8916608482015260a4810188905260c4810187905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561161157600080fd5b505af1158015611625573d6000803e3d6000fd5b505050506116378d8d8d8d8d8d611feb565b9d9c50505050505050505050505050565b804281101561168c576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b6117018585600081811061169c57fe5b905060200201356001600160a01b0316336116fb7f0000000000000000000000000000000000000000000000000000000000000000898960008181106116de57fe5b905060200201356001600160a01b03168a8a600181811061100457fe5b8a613564565b60008585600019810181811061171357fe5b905060200201356001600160a01b03166001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561177857600080fd5b505afa15801561178c573d6000803e3d6000fd5b505050506040513d60208110156117a257600080fd5b505160408051602088810282810182019093528882529293506117e4929091899189918291850190849080828437600092019190915250889250613a3f915050565b8661189682888860001981018181106117f957fe5b905060200201356001600160a01b03166001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561185e57600080fd5b505afa158015611872573d6000803e3d6000fd5b505050506040513d602081101561188857600080fd5b50519063ffffffff613d5116565b10156118d35760405162461bcd60e51b815260040180806020018281038252602b8152602001806145c0602b913960400191505060405180910390fd5b5050505050505050565b8042811015611921576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585600019810181811061195b57fe5b905060200201356001600160a01b03166001600160a01b0316146119b4576040805162461bcd60e51b815260206004820152601d602482015260008051602061457a833981519152604482015290519081900360640190fd5b6119c48585600081811061169c57fe5b611a02858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613a3f915050565b604080516370a0823160e01b815230600482015290516000916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a0823191602480820192602092909190829003018186803b158015611a6c57600080fd5b505afa158015611a80573d6000803e3d6000fd5b505050506040513d6020811015611a9657600080fd5b5051905086811015611ad95760405162461bcd60e51b815260040180806020018281038252602b8152602001806145c0602b913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611b3f57600080fd5b505af1158015611b53573d6000803e3d6000fd5b505050506118d38482613158565b60608142811015611ba7576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686866000818110611bde57fe5b905060200201356001600160a01b03166001600160a01b031614611c37576040805162461bcd60e51b815260206004820152601d602482015260008051602061457a833981519152604482015290519081900360640190fd5b611c957f00000000000000000000000000000000000000000000000000000000000000003488888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061334092505050565b91508682600184510381518110611ca857fe5b60200260200101511015611ced5760405162461bcd60e51b815260040180806020018281038252602b8152602001806145c0602b913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db083600081518110611d2957fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d5c57600080fd5b505af1158015611d70573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb611dd57f0000000000000000000000000000000000000000000000000000000000000000898960008181106116de57fe5b84600081518110611de257fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611e3957600080fd5b505af1158015611e4d573d6000803e3d6000fd5b505050506040513d6020811015611e6357600080fd5b5051611e6b57fe5b611eaa828787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508992506136c1915050565b5095945050505050565b6000610dfe848484613da9565b60608142811015611f07576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b611f657f00000000000000000000000000000000000000000000000000000000000000008988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061390792505050565b91508682600081518110611f7557fe5b6020026020010151111561135f5760405162461bcd60e51b81526004018080602001828103825260278152602001806145536027913960400191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610dfe848484613e99565b60008142811015612031576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b612060887f000000000000000000000000000000000000000000000000000000000000000089898930896124f8565b604080516370a0823160e01b815230600482015290519194506120e492508a9187916001600160a01b038416916370a0823191602480820192602092909190829003018186803b1580156120b357600080fd5b505afa1580156120c7573d6000803e3d6000fd5b505050506040513d60208110156120dd57600080fd5b5051613004565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561214a57600080fd5b505af115801561215e573d6000803e3d6000fd5b505050506111288483613158565b80428110156121b0576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316858560008181106121e757fe5b905060200201356001600160a01b03166001600160a01b031614612240576040805162461bcd60e51b815260206004820152601d602482015260008051602061457a833981519152604482015290519081900360640190fd5b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6123197f0000000000000000000000000000000000000000000000000000000000000000898960008181106116de57fe5b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561236957600080fd5b505af115801561237d573d6000803e3d6000fd5b505050506040513d602081101561239357600080fd5b505161239b57fe5b6000868660001981018181106123ad57fe5b905060200201356001600160a01b03166001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561241257600080fd5b505afa158015612426573d6000803e3d6000fd5b505050506040513d602081101561243c57600080fd5b5051604080516020898102828101820190935289825292935061247e9290918a918a918291850190849080828437600092019190915250899250613a3f915050565b87611896828989600019810181811061249357fe5b905060200201356001600160a01b03166001600160a01b03166370a08231896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561185e57600080fd5b600080824281101561253f576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b600061256c7f00000000000000000000000000000000000000000000000000000000000000008c8c61348c565b604080516323b872dd60e01b81523360048201526001600160a01b03831660248201819052604482018d9052915192935090916323b872dd916064808201926020929091908290030181600087803b1580156125c757600080fd5b505af11580156125db573d6000803e3d6000fd5b505050506040513d60208110156125f157600080fd5b50506040805163226bf2d160e21b81526001600160a01b03888116600483015282516000938493928616926389afcb44926024808301939282900301818787803b15801561263e57600080fd5b505af1158015612652573d6000803e3d6000fd5b505050506040513d604081101561266857600080fd5b508051602090910151909250905060006126828e8e613f45565b509050806001600160a01b03168e6001600160a01b0316146126a55781836126a8565b82825b90975095508a8710156126ec5760405162461bcd60e51b815260040180806020018281038252602681526020018061459a6026913960400191505060405180910390fd5b8986101561272b5760405162461bcd60e51b81526004018080602001828103825260268152602001806144e06026913960400191505060405180910390fd5b505050505097509795505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60606111607f00000000000000000000000000000000000000000000000000000000000000008484613340565b60008060006127dd7f00000000000000000000000000000000000000000000000000000000000000008e7f000000000000000000000000000000000000000000000000000000000000000061348c565b90506000876127ec578c6127f0565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561286657600080fd5b505af115801561287a573d6000803e3d6000fd5b5050505061288c8e8e8e8e8e8e610cd7565b909f909e509c50505050505050505050505050565b600080600083428110156128ea576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b6128f88c8c8c8c8c8c614023565b9094509250600061292a7f00000000000000000000000000000000000000000000000000000000000000008e8e61348c565b90506129388d338388613564565b6129448c338387613564565b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561299c57600080fd5b505af11580156129b0573d6000803e3d6000fd5b505050506040513d60208110156129c657600080fd5b5051949d939c50939a509198505050505050505050565b60008060008342811015612a26576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b612a548a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c614023565b90945092506000612aa67f00000000000000000000000000000000000000000000000000000000000000008c7f000000000000000000000000000000000000000000000000000000000000000061348c565b9050612ab48b338388613564565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612b0f57600080fd5b505af1158015612b23573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb82866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612ba857600080fd5b505af1158015612bbc573d6000803e3d6000fd5b505050506040513d6020811015612bd257600080fd5b5051612bda57fe5b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015612c3257600080fd5b505af1158015612c46573d6000803e3d6000fd5b505050506040513d6020811015612c5c57600080fd5b5051925034841015612c7457612c7433853403613158565b505096509650969350505050565b60608142811015612cc8576040805162461bcd60e51b81526020600482015260186024820152600080516020614643833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686866000818110612cff57fe5b905060200201356001600160a01b03166001600160a01b031614612d58576040805162461bcd60e51b815260206004820152601d602482015260008051602061457a833981519152604482015290519081900360640190fd5b612db67f00000000000000000000000000000000000000000000000000000000000000008888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061390792505050565b91503482600081518110612dc657fe5b60200260200101511115612e0b5760405162461bcd60e51b81526004018080602001828103825260278152602001806145536027913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db083600081518110612e4757fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015612e7a57600080fd5b505af1158015612e8e573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb612ef37f0000000000000000000000000000000000000000000000000000000000000000898960008181106116de57fe5b84600081518110612f0057fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612f5757600080fd5b505af1158015612f6b573d6000803e3d6000fd5b505050506040513d6020811015612f8157600080fd5b5051612f8957fe5b612fc8828787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508992506136c1915050565b81600081518110612fd557fe5b6020026020010151341115611eaa57611eaa3383600081518110612ff557fe5b60200260200101513403613158565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b602083106130815780518252601f199092019160209182019101613062565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146130e3576040519150601f19603f3d011682016040523d82523d6000602084013e6130e8565b606091505b5091509150818015613116575080511580613116575080806020019051602081101561311357600080fd5b50515b6131515760405162461bcd60e51b815260040180806020018281038252602d8152602001806145eb602d913960400191505060405180910390fd5b5050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106131a45780518252601f199092019160209182019101613185565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613206576040519150601f19603f3d011682016040523d82523d6000602084013e61320b565b606091505b505090508061324b5760405162461bcd60e51b81526004018080602001828103825260348152602001806144876034913960400191505060405180910390fd5b505050565b60008084116132905760405162461bcd60e51b815260040180806020018281038252602b815260200180614618602b913960400191505060405180910390fd5b6000831180156132a05750600082115b6132db5760405162461bcd60e51b81526004018080602001828103825260288152602001806145066028913960400191505060405180910390fd5b60006132ef856103e563ffffffff61429716565b90506000613303828563ffffffff61429716565b905060006133298361331d886103e863ffffffff61429716565b9063ffffffff61430316565b905080828161333457fe5b04979650505050505050565b6060600282511015613399576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a20494e56414c49445f504154480000604482015290519081900360640190fd5b815167ffffffffffffffff811180156133b157600080fd5b506040519080825280602002602001820160405280156133db578160200160208202803683370190505b50905082816000815181106133ec57fe5b60200260200101818152505060005b60018351038110156134845760008061343e8786858151811061341a57fe5b602002602001015187866001018151811061343157fe5b602002602001015161435b565b9150915061346084848151811061345157fe5b60200260200101518383613250565b84846001018151811061346f57fe5b602090810291909101015250506001016133fb565b509392505050565b600080600061349b8585613f45565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527fa0d4c4d350f7cfd6c7d95a457ff8f843364762e67e907544c7ec6b369852f437609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b602083106135e95780518252601f1990920191602091820191016135ca565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461364b576040519150601f19603f3d011682016040523d82523d6000602084013e613650565b606091505b509150915081801561367e57508051158061367e575080806020019051602081101561367b57600080fd5b50515b6136b95760405162461bcd60e51b81526004018080602001828103825260318152602001806144566031913960400191505060405180910390fd5b505050505050565b60005b6001835103811015613901576000808483815181106136df57fe5b60200260200101518584600101815181106136f657fe5b602002602001015191509150600061370e8383613f45565b509050600087856001018151811061372257fe5b60200260200101519050600080836001600160a01b0316866001600160a01b03161461375057826000613754565b6000835b91509150600060028a5103881061376b57886137ac565b6137ac7f0000000000000000000000000000000000000000000000000000000000000000878c8b6002018151811061379f57fe5b602002602001015161348c565b90506137d97f0000000000000000000000000000000000000000000000000000000000000000888861348c565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613816576020820181803683370190505b506040518563ffffffff1660e01b815260040180858152602001848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561388757818101518382015260200161386f565b50505050905090810190601f1680156138b45780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156138d657600080fd5b505af11580156138ea573d6000803e3d6000fd5b5050600190990198506136c4975050505050505050565b50505050565b6060600282511015613960576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a20494e56414c49445f504154480000604482015290519081900360640190fd5b815167ffffffffffffffff8111801561397857600080fd5b506040519080825280602002602001820160405280156139a2578160200160208202803683370190505b50905082816001835103815181106139b657fe5b60209081029190910101528151600019015b8015613484576000806139f8878660018603815181106139e457fe5b602002602001015187868151811061343157fe5b91509150613a1a848481518110613a0b57fe5b60200260200101518383613da9565b846001850381518110613a2957fe5b60209081029190910101525050600019016139c8565b60005b600183510381101561324b57600080848381518110613a5d57fe5b6020026020010151858460010181518110613a7457fe5b6020026020010151915091506000613a8c8383613f45565b5090506000613abc7f0000000000000000000000000000000000000000000000000000000000000000858561348c565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015613afd57600080fd5b505afa158015613b11573d6000803e3d6000fd5b505050506040513d6060811015613b2757600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506000806001600160a01b038a811690891614613b64578284613b67565b83835b91509150613bc5828b6001600160a01b03166370a082318a6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561185e57600080fd5b9550613bd2868383613250565b945050505050600080856001600160a01b0316886001600160a01b031614613bfc57826000613c00565b6000835b91509150600060028c51038a10613c17578a613c4b565b613c4b7f0000000000000000000000000000000000000000000000000000000000000000898e8d6002018151811061379f57fe5b604080516000808252602082019283905263022c0d9f60e01b835260248201878152604483018790526001600160a01b038086166064850152608060848501908152845160a48601819052969750908c169563022c0d9f958a958a958a9591949193919260c486019290918190849084905b83811015613cd5578181015183820152602001613cbd565b50505050905090810190601f168015613d025780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015613d2457600080fd5b505af1158015613d38573d6000803e3d6000fd5b50506001909b019a50613a429950505050505050505050565b80820382811115611163576040805162461bcd60e51b815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6000808411613de95760405162461bcd60e51b815260040180806020018281038252602c81526020018061442a602c913960400191505060405180910390fd5b600083118015613df95750600082115b613e345760405162461bcd60e51b81526004018080602001828103825260288152602001806145066028913960400191505060405180910390fd5b6000613e586103e8613e4c868863ffffffff61429716565b9063ffffffff61429716565b90506000613e726103e5613e4c868963ffffffff613d5116565b9050613e8f6001828481613e8257fe5b049063ffffffff61430316565b9695505050505050565b6000808411613ed95760405162461bcd60e51b815260040180806020018281038252602581526020018061452e6025913960400191505060405180910390fd5b600083118015613ee95750600082115b613f245760405162461bcd60e51b81526004018080602001828103825260288152602001806145066028913960400191505060405180910390fd5b82613f35858463ffffffff61429716565b81613f3c57fe5b04949350505050565b600080826001600160a01b0316846001600160a01b03161415613f995760405162461bcd60e51b81526004018080602001828103825260258152602001806144bb6025913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b031610613fb9578284613fbc565b83835b90925090506001600160a01b03821661401c576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b9250929050565b6040805163e6a4390560e01b81526001600160a01b03888116600483015287811660248301529151600092839283927f00000000000000000000000000000000000000000000000000000000000000009092169163e6a4390591604480820192602092909190829003018186803b15801561409d57600080fd5b505afa1580156140b1573d6000803e3d6000fd5b505050506040513d60208110156140c757600080fd5b50516001600160a01b0316141561417a57604080516364e329cb60e11b81526001600160a01b038a81166004830152898116602483015291517f00000000000000000000000000000000000000000000000000000000000000009092169163c9c65396916044808201926020929091908290030181600087803b15801561414d57600080fd5b505af1158015614161573d6000803e3d6000fd5b505050506040513d602081101561417757600080fd5b50505b6000806141a87f00000000000000000000000000000000000000000000000000000000000000008b8b61435b565b915091508160001480156141ba575080155b156141ca5787935086925061428a565b60006141d7898484613e99565b905087811161422a578581101561421f5760405162461bcd60e51b81526004018080602001828103825260268152602001806144e06026913960400191505060405180910390fd5b889450925082614288565b6000614237898486613e99565b90508981111561424357fe5b878110156142825760405162461bcd60e51b815260040180806020018281038252602681526020018061459a6026913960400191505060405180910390fd5b94508793505b505b5050965096945050505050565b60008115806142b2575050808202828282816142af57fe5b04145b611163576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820182811015611163576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b600080600061436a8585613f45565b50905060008061437b88888861348c565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156143b357600080fd5b505afa1580156143c7573d6000803e3d6000fd5b505050506040513d60608110156143dd57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b038781169084161461441757808261441a565b81815b9099909850965050505050505056fe556e697377617056324c6962726172793a20494e53554646494349454e545f4f55545055545f414d4f554e545472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472616e7366657246726f6d206661696c65645472616e7366657248656c7065723a3a736166655472616e736665724554483a20455448207472616e73666572206661696c6564556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553556e69737761705632526f757465723a20494e53554646494349454e545f425f414d4f554e54556e697377617056324c6962726172793a20494e53554646494349454e545f4c4951554944495459556e697377617056324c6962726172793a20494e53554646494349454e545f414d4f554e54556e69737761705632526f757465723a204558434553534956455f494e5055545f414d4f554e54556e69737761705632526f757465723a20494e56414c49445f50415448000000556e69737761705632526f757465723a20494e53554646494349454e545f415f414d4f554e54556e69737761705632526f757465723a20494e53554646494349454e545f4f55545055545f414d4f554e545472616e7366657248656c7065723a3a736166655472616e736665723a207472616e73666572206661696c6564556e697377617056324c6962726172793a20494e53554646494349454e545f494e5055545f414d4f554e54556e69737761705632526f757465723a20455850495245440000000000000000a264697066735822122023d3b6563fcbec622d71c4f82d59e3d6bb6ac6cb7c19fbc3eda449b69c912fed64736f6c63430006060033 \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/contract/UniswapV2Router02.sol b/benchmark/ethereum/uniswap/contract/UniswapV2Router02.sol new file mode 100644 index 0000000..cb40e96 --- /dev/null +++ b/benchmark/ethereum/uniswap/contract/UniswapV2Router02.sol @@ -0,0 +1,451 @@ +pragma solidity =0.6.6; + +import '../v2-core/interfaces/IUniswapV2Factory.sol'; +import '../lib/TransferHelper.sol'; + +import '../v2-periphery/interfaces/IUniswapV2Router02.sol'; +import '../v2-periphery/libraries/UniswapV2Library.sol'; +import '../v2-periphery/libraries/SafeMath.sol'; +import '../v2-periphery/interfaces/IERC20.sol'; +import '../v2-periphery/interfaces/IWETH.sol'; + +// 不实际使用,仅做备案 +contract UniswapV2Router02 is IUniswapV2Router02 { + using SafeMath for uint; + + address public immutable override factory; + address public immutable override WETH; + + modifier ensure(uint deadline) { + require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED'); + _; + } + + constructor() public { + factory = 0x10Fdfb83Fb801E4bB80219411e9eC437AeC1e105; + WETH = 0x5aea6ea637074b48fdFb32Ad9291009E03d0cB2d; + } + + function getThisContractAddress() public view returns (address) { + return address(this); + } + + receive() external payable { + assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract + } + + // **** ADD LIQUIDITY **** + function _addLiquidity( + address tokenA, + address tokenB, + uint amountADesired, + uint amountBDesired, + uint amountAMin, + uint amountBMin + ) internal virtual returns (uint amountA, uint amountB) { + // create the pair if it doesn't exist yet + if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { + IUniswapV2Factory(factory).createPair(tokenA, tokenB); + } + (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); + if (reserveA == 0 && reserveB == 0) { + (amountA, amountB) = (amountADesired, amountBDesired); + } else { + uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); + if (amountBOptimal <= amountBDesired) { + require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + (amountA, amountB) = (amountADesired, amountBOptimal); + } else { + uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); + assert(amountAOptimal <= amountADesired); + require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); + (amountA, amountB) = (amountAOptimal, amountBDesired); + } + } + } + function addLiquidity( + address tokenA, + address tokenB, + uint amountADesired, + uint amountBDesired, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) { + (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin); + address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); + TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB); + liquidity = IUniswapV2Pair(pair).mint(to); + } + function addLiquidityETH( + address token, + uint amountTokenDesired, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) { + (amountToken, amountETH) = _addLiquidity( + token, + WETH, + amountTokenDesired, + msg.value, + amountTokenMin, + amountETHMin + ); + address pair = UniswapV2Library.pairFor(factory, token, WETH); + TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken); + IWETH(WETH).deposit{value: amountETH}(); + assert(IWETH(WETH).transfer(pair, amountETH)); + liquidity = IUniswapV2Pair(pair).mint(to); + // refund dust eth, if any + if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); + } + + // **** REMOVE LIQUIDITY **** + function removeLiquidity( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) { + address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair + (uint amount0, uint amount1) = IUniswapV2Pair(pair).burn(to); + (address token0,) = UniswapV2Library.sortTokens(tokenA, tokenB); + (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); + require(amountA >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); + require(amountB >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + } + function removeLiquidityETH( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) { + (amountToken, amountETH) = removeLiquidity( + token, + WETH, + liquidity, + amountTokenMin, + amountETHMin, + address(this), + deadline + ); + TransferHelper.safeTransfer(token, to, amountToken); + IWETH(WETH).withdraw(amountETH); + TransferHelper.safeTransferETH(to, amountETH); + } + function removeLiquidityWithPermit( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external virtual override returns (uint amountA, uint amountB) { + address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + uint value = approveMax ? uint(-1) : liquidity; + IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline); + } + function removeLiquidityETHWithPermit( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external virtual override returns (uint amountToken, uint amountETH) { + address pair = UniswapV2Library.pairFor(factory, token, WETH); + uint value = approveMax ? uint(-1) : liquidity; + IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline); + } + + // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) **** + function removeLiquidityETHSupportingFeeOnTransferTokens( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) public virtual override ensure(deadline) returns (uint amountETH) { + (, amountETH) = removeLiquidity( + token, + WETH, + liquidity, + amountTokenMin, + amountETHMin, + address(this), + deadline + ); + TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this))); + IWETH(WETH).withdraw(amountETH); + TransferHelper.safeTransferETH(to, amountETH); + } + function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external virtual override returns (uint amountETH) { + address pair = UniswapV2Library.pairFor(factory, token, WETH); + uint value = approveMax ? uint(-1) : liquidity; + IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + amountETH = removeLiquidityETHSupportingFeeOnTransferTokens( + token, liquidity, amountTokenMin, amountETHMin, to, deadline + ); + } + + // **** SWAP **** + // requires the initial amount to have already been sent to the first pair + function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual { + for (uint i; i < path.length - 1; i++) { + (address input, address output) = (path[i], path[i + 1]); + (address token0,) = UniswapV2Library.sortTokens(input, output); + uint amountOut = amounts[i + 1]; + (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); + address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; + IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)).swap( + amount0Out, amount1Out, to, new bytes(0) + ); + } + } + function swapExactTokensForTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external virtual override ensure(deadline) returns (uint[] memory amounts) { + amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, to); + } + function swapTokensForExactTokens( + uint amountOut, + uint amountInMax, + address[] calldata path, + address to, + uint deadline + ) external virtual override ensure(deadline) returns (uint[] memory amounts) { + amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, to); + } + function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) + external + virtual + override + payable + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + IWETH(WETH).deposit{value: amounts[0]}(); + assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + _swap(amounts, path, to); + } + function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) + external + virtual + override + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, address(this)); + IWETH(WETH).withdraw(amounts[amounts.length - 1]); + TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); + } + function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) + external + virtual + override + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, address(this)); + IWETH(WETH).withdraw(amounts[amounts.length - 1]); + TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); + } + function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) + external + virtual + override + payable + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= msg.value, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + IWETH(WETH).deposit{value: amounts[0]}(); + assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + _swap(amounts, path, to); + // refund dust eth, if any + if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); + } + + // **** SWAP (supporting fee-on-transfer tokens) **** + // requires the initial amount to have already been sent to the first pair + function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual { + for (uint i; i < path.length - 1; i++) { + (address input, address output) = (path[i], path[i + 1]); + (address token0,) = UniswapV2Library.sortTokens(input, output); + IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)); + uint amountInput; + uint amountOutput; + { // scope to avoid stack too deep errors + (uint reserve0, uint reserve1,) = pair.getReserves(); + (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); + amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput); + amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); + } + (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); + address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; + pair.swap(amount0Out, amount1Out, to, new bytes(0)); + } + } + function swapExactTokensForTokensSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external virtual override ensure(deadline) { + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn + ); + uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); + _swapSupportingFeeOnTransferTokens(path, to); + require( + IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, + 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' + ); + } + function swapExactETHForTokensSupportingFeeOnTransferTokens( + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) + external + virtual + override + payable + ensure(deadline) + { + require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + uint amountIn = msg.value; + IWETH(WETH).deposit{value: amountIn}(); + assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn)); + uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); + _swapSupportingFeeOnTransferTokens(path, to); + require( + IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, + 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' + ); + } + function swapExactTokensForETHSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) + external + virtual + override + ensure(deadline) + { + require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn + ); + _swapSupportingFeeOnTransferTokens(path, address(this)); + uint amountOut = IERC20(WETH).balanceOf(address(this)); + require(amountOut >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + IWETH(WETH).withdraw(amountOut); + TransferHelper.safeTransferETH(to, amountOut); + } + + // **** LIBRARY FUNCTIONS **** + function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) { + return UniswapV2Library.quote(amountA, reserveA, reserveB); + } + + function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) + public + pure + virtual + override + returns (uint amountOut) + { + return UniswapV2Library.getAmountOut(amountIn, reserveIn, reserveOut); + } + + function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) + public + pure + virtual + override + returns (uint amountIn) + { + return UniswapV2Library.getAmountIn(amountOut, reserveIn, reserveOut); + } + + function getAmountsOut(uint amountIn, address[] memory path) + public + view + virtual + override + returns (uint[] memory amounts) + { + return UniswapV2Library.getAmountsOut(factory, amountIn, path); + } + + function getAmountsIn(uint amountOut, address[] memory path) + public + view + virtual + override + returns (uint[] memory amounts) + { + return UniswapV2Library.getAmountsIn(factory, amountOut, path); + } +} diff --git a/benchmark/ethereum/uniswap/eth/eth.toml b/benchmark/ethereum/uniswap/eth/eth.toml new file mode 100644 index 0000000..3c765d8 --- /dev/null +++ b/benchmark/ethereum/uniswap/eth/eth.toml @@ -0,0 +1,3 @@ +[rpc] +node = "http://127.0.0.1" +port = "8881" \ No newline at end of file diff --git a/benchmark/ethereum/uniswap/script.lua b/benchmark/ethereum/uniswap/script.lua new file mode 100755 index 0000000..e658f34 --- /dev/null +++ b/benchmark/ethereum/uniswap/script.lua @@ -0,0 +1,186 @@ +local case = testcase.new() + +function case:BeforeRun() + fromAddr = self.blockchain:GetRandomAccountByGroup() + self.amountToken = 1000000000000000000000 + amount = self.amountToken + local routerAddr = self.blockchain:GetContractAddrByName("UniswapV2Router02") + --print(routerAddr) + + local tokens = {"Token1", "Token2", "Token3"} + local multipliers = {1, 10, 100} + + for i, token in ipairs(tokens) do + local mintAmount = amount * multipliers[i] + + local result = self.blockchain:Invoke({ + caller = fromAddr, + contract = token, + func = "mint", + args = {fromAddr, mintAmount}, + }) + + local approveRes = self.blockchain:Invoke({ + caller = fromAddr, + contract = token, + func = "approve", + args = {routerAddr, mintAmount} + }) + end + + deadline = os.time() + 1000 + local token1 = self.blockchain:GetContractAddrByName("Token1") + local token2 = self.blockchain:GetContractAddrByName("Token2") + local token3 = self.blockchain:GetContractAddrByName("Token3") + + local token1token2Liquid = self.blockchain:Invoke({ + caller = fromAddr, + contract = "UniswapV2Router02", + func = "addLiquidity", + args ={ + token1, + token2, + amount * 0.5, + amount * 0.5 * 10, + amount * 0.4, + amount * 0.4 * 10, + fromAddr, + deadline, + }, + }) + + local token2token3Liquid = self.blockchain:Invoke({ + caller = fromAddr, + contract = "UniswapV2Router02", + func = "addLiquidity", + args ={ + token2, + token3, + amount * 0.5 * 10, + amount * 0.5 * 100, + amount * 0.4 * 10, + amount * 0.4 * 100, + fromAddr, + deadline, + }, + }) + + local token1token3Liquid = self.blockchain:Invoke({ + caller = fromAddr, + contract = "UniswapV2Router02", + func = "addLiquidity", + args ={ + token1, + token3, + amount * 0.5, + amount * 0.5 * 100, + amount * 0.4, + amount * 0.4 * 100, + fromAddr, + deadline, + }, + }) + + return {type = "default addLiquidity", result = token1token3Liquid} +end + +function case:Run() + -- 获取随机地址 + addr = self.blockchain:GetRandomAccountByGroup() + amount = self.amountToken + + -- 获取一个随机数 + random = self.toolkit.RandInt(0, 1) + + if random == 0 then + -- 随机选择token对进行添加流动性 + pair_choice = self.toolkit.RandInt(1, 3) + local tokenA, tokenB + if pair_choice == 1 then + tokenA = "Token1" + tokenB = "Token2" + elseif pair_choice == 2 then + tokenA = "Token2" + tokenB = "Token3" + else + tokenA = "Token1" + tokenB = "Token3" + end + + -- 授权 TokenA + local approveTokenA = self.blockchain:Invoke({ + caller = addr, + contract = tokenA, + func = "approve", + args = {self.blockchain:GetContractAddrByName("UniswapV2Router02"), amount * 1} + }) + + -- 授权 TokenB + local approveTokenB = self.blockchain:Invoke({ + caller = addr, + contract = tokenB, + func = "approve", + args = {self.blockchain:GetContractAddrByName("UniswapV2Router02"), amount * 1} + }) + + -- 添加流动性 + deadline = os.time() + 1000 + local addLiquidity = self.blockchain:Invoke({ + caller = addr, + contract = "UniswapV2Router02", + func = "addLiquidity", + args ={ + self.blockchain:GetContractAddrByName(tokenA), + self.blockchain:GetContractAddrByName(tokenB), + amount * 1, + amount * 1, + amount * 0.01, + amount * 0.01, + addr, + deadline, + }, + }) + return {type = "addLiquidity", result = addLiquidity} + + else + -- mint + token_choice = self.toolkit.RandInt(1, 3) + if token_choice == 1 then + token_name = "Token1" + elseif token_choice == 2 then + token_name = "Token2" + else + token_name = "Token3" + end + + local mintResult = self.blockchain:Invoke({ + caller = addr, + contract = token_name, + func = "mint", + args = {addr, amount}, + }) + + -- swap + local swapTokens = {"Token1", "Token2", "Token3"} + table.remove(swapTokens, token_choice) -- 移除已经mint的token + + local inputToken = self.blockchain:GetContractAddrByName(swapTokens[1]) + local outputToken = self.blockchain:GetContractAddrByName(swapTokens[2]) + + local swapResult = self.blockchain:Invoke({ + caller = addr, + contract = "UniswapV2Router02", + func = "swapExactTokensForTokens", + args = { + amount * 0.05, -- 交换的数量 + 0, -- 最小输出数量 + {inputToken, outputToken}, -- 交换路径 + addr, -- 接收地址 + deadline, + }, + }) + return {type = "swapResult", result = swapResult} + + end +end +return case diff --git a/benchmark/fabric/Sacc/contract/sacc.go b/benchmark/fabric/Sacc/contract/sacc.go index 4bfb165..dfc0636 100644 --- a/benchmark/fabric/Sacc/contract/sacc.go +++ b/benchmark/fabric/Sacc/contract/sacc.go @@ -6,92 +6,92 @@ package main -import ( - "fmt" +// import ( +// "fmt" - "github.com/hyperledger/fabric/core/chaincode/shim" - "github.com/hyperledger/fabric/protos/peer" -) +// "github.com/hyperledger/fabric/core/chaincode/shim" +// "github.com/hyperledger/fabric/protos/peer" +// ) -// SimpleAsset implements a simple chaincode to manage an asset -type SimpleAsset struct { -} +// // SimpleAsset implements a simple chaincode to manage an asset +// type SimpleAsset struct { +// } -// Init is called during chaincode instantiation to initialize any -// data. Note that chaincode upgrade also calls this function to reset -// or to migrate data. -func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response { - // Get the args from the transaction proposal - args := stub.GetStringArgs() - if len(args) != 2 { - return shim.Error("Incorrect arguments. Expecting a key and a value") - } +// // Init is called during chaincode instantiation to initialize any +// // data. Note that chaincode upgrade also calls this function to reset +// // or to migrate data. +// func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response { +// // Get the args from the transaction proposal +// args := stub.GetStringArgs() +// if len(args) != 2 { +// return shim.Error("Incorrect arguments. Expecting a key and a value") +// } - // Set up any variables or assets here by calling stub.PutState() +// // Set up any variables or assets here by calling stub.PutState() - // We store the key and the value on the ledger - err := stub.PutState(args[0], []byte(args[1])) - if err != nil { - return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0])) - } - return shim.Success(nil) -} +// // We store the key and the value on the ledger +// err := stub.PutState(args[0], []byte(args[1])) +// if err != nil { +// return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0])) +// } +// return shim.Success(nil) +// } -// Invoke is called per transaction on the chaincode. Each transaction is -// either a 'get' or a 'set' on the asset created by Init function. The Set -// method may create a new asset by specifying a new key-value pair. -func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response { - // Extract the function and args from the transaction proposal - fn, args := stub.GetFunctionAndParameters() +// // Invoke is called per transaction on the chaincode. Each transaction is +// // either a 'get' or a 'set' on the asset created by Init function. The Set +// // method may create a new asset by specifying a new key-value pair. +// func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response { +// // Extract the function and args from the transaction proposal +// fn, args := stub.GetFunctionAndParameters() - var result string - var err error - if fn == "set" { - result, err = set(stub, args) - } else { // assume 'get' even if fn is nil - result, err = get(stub, args) - } - if err != nil { - return shim.Error(err.Error()) - } +// var result string +// var err error +// if fn == "set" { +// result, err = set(stub, args) +// } else { // assume 'get' even if fn is nil +// result, err = get(stub, args) +// } +// if err != nil { +// return shim.Error(err.Error()) +// } - // Return the result as success payload - return shim.Success([]byte(result)) -} +// // Return the result as success payload +// return shim.Success([]byte(result)) +// } -// Set stores the asset (both key and value) on the ledger. If the key exists, -// it will override the value with the new one -func set(stub shim.ChaincodeStubInterface, args []string) (string, error) { - if len(args) != 2 { - return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value") - } +// // Set stores the asset (both key and value) on the ledger. If the key exists, +// // it will override the value with the new one +// func set(stub shim.ChaincodeStubInterface, args []string) (string, error) { +// if len(args) != 2 { +// return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value") +// } - err := stub.PutState(args[0], []byte(args[1])) - if err != nil { - return "", fmt.Errorf("Failed to set asset: %s", args[0]) - } - return args[1], nil -} +// err := stub.PutState(args[0], []byte(args[1])) +// if err != nil { +// return "", fmt.Errorf("Failed to set asset: %s", args[0]) +// } +// return args[1], nil +// } -// Get returns the value of the specified asset key -func get(stub shim.ChaincodeStubInterface, args []string) (string, error) { - if len(args) != 1 { - return "", fmt.Errorf("Incorrect arguments. Expecting a key") - } +// // Get returns the value of the specified asset key +// func get(stub shim.ChaincodeStubInterface, args []string) (string, error) { +// if len(args) != 1 { +// return "", fmt.Errorf("Incorrect arguments. Expecting a key") +// } - value, err := stub.GetState(args[0]) - if err != nil { - return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err) - } - if value == nil { - return "", fmt.Errorf("Asset not found: %s", args[0]) - } - return string(value), nil -} +// value, err := stub.GetState(args[0]) +// if err != nil { +// return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err) +// } +// if value == nil { +// return "", fmt.Errorf("Asset not found: %s", args[0]) +// } +// return string(value), nil +// } -// main function starts up the chaincode in the container during instantiate -func main() { - if err := shim.Start(new(SimpleAsset)); err != nil { - fmt.Printf("Error starting SimpleAsset chaincode: %s", err) - } -} +// // main function starts up the chaincode in the container during instantiate +// func main() { +// if err := shim.Start(new(SimpleAsset)); err != nil { +// fmt.Printf("Error starting SimpleAsset chaincode: %s", err) +// } +// } \ No newline at end of file diff --git a/benchmark/fabric/example/contract/chaincode_example02.go b/benchmark/fabric/example/contract/chaincode_example02.go index ebc9dcb..210a134 100644 --- a/benchmark/fabric/example/contract/chaincode_example02.go +++ b/benchmark/fabric/example/contract/chaincode_example02.go @@ -22,180 +22,180 @@ package main //chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of //hard-coding. -import ( - "fmt" - "strconv" - - "github.com/hyperledger/fabric/core/chaincode/shim" - pb "github.com/hyperledger/fabric/protos/peer" -) - -// SimpleChaincode example simple Chaincode implementation -type SimpleChaincode struct { -} - -// Init implement Chaincode -func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { - fmt.Println("ex02 Init") - _, args := stub.GetFunctionAndParameters() - var A, B string // Entities - var Aval, Bval int // Asset holdings - var err error - - if len(args) != 4 { - return shim.Error("Incorrect number of arguments. Expecting 4") - } - - // Initialize the chaincode - A = args[0] - Aval, err = strconv.Atoi(args[1]) - if err != nil { - return shim.Error("Expecting integer value for asset holding") - } - B = args[2] - Bval, err = strconv.Atoi(args[3]) - if err != nil { - return shim.Error("Expecting integer value for asset holding") - } - fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) - - // Write the state to the ledger - err = stub.PutState(A, []byte(strconv.Itoa(Aval))) - if err != nil { - return shim.Error(err.Error()) - } - - err = stub.PutState(B, []byte(strconv.Itoa(Bval))) - if err != nil { - return shim.Error(err.Error()) - } - - return shim.Success(nil) -} - -// Invoke implement Chaincode -func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { - fmt.Println("ex02 Invoke") - function, args := stub.GetFunctionAndParameters() - if function == "invoke" { - // Make payment of X units from A to B - return t.invoke(stub, args) - } else if function == "delete" { - // Deletes an entity from its state - return t.delete(stub, args) - } else if function == "query" { - // the old "Query" is now implemtned in invoke - return t.query(stub, args) - } - - return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"") -} - -// Transaction makes payment of X units from A to B -func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { - var A, B string // Entities - var Aval, Bval int // Asset holdings - var X int // Transaction value - var err error - - if len(args) != 3 { - return shim.Error("Incorrect number of arguments. Expecting 3") - } - - A = args[0] - B = args[1] - - // Get the state from the ledger - // TODO: will be nice to have a GetAllState call to ledger - Avalbytes, err := stub.GetState(A) - if err != nil { - return shim.Error("Failed to get state") - } - if Avalbytes == nil { - return shim.Error("Entity not found") - } - Aval, _ = strconv.Atoi(string(Avalbytes)) - - Bvalbytes, err := stub.GetState(B) - if err != nil { - return shim.Error("Failed to get state") - } - if Bvalbytes == nil { - return shim.Error("Entity not found") - } - Bval, _ = strconv.Atoi(string(Bvalbytes)) - - // Perform the execution - X, err = strconv.Atoi(args[2]) - if err != nil { - return shim.Error("Invalid transaction amount, expecting a integer value") - } - Aval = Aval - X - Bval = Bval + X - fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) - - // Write the state back to the ledger - err = stub.PutState(A, []byte(strconv.Itoa(Aval))) - if err != nil { - return shim.Error(err.Error()) - } - - err = stub.PutState(B, []byte(strconv.Itoa(Bval))) - if err != nil { - return shim.Error(err.Error()) - } - - return shim.Success(nil) -} - -// Deletes an entity from state -func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { - if len(args) != 1 { - return shim.Error("Incorrect number of arguments. Expecting 1") - } - - A := args[0] - - // Delete the key from the state in ledger - err := stub.DelState(A) - if err != nil { - return shim.Error("Failed to delete state") - } - - return shim.Success(nil) -} - -// query callback representing the query of a chaincode -func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { - var A string // Entities - var err error - - if len(args) != 1 { - return shim.Error("Incorrect number of arguments. Expecting name of the person to query") - } - - A = args[0] - - // Get the state from the ledger - Avalbytes, err := stub.GetState(A) - if err != nil { - jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" - return shim.Error(jsonResp) - } - - if Avalbytes == nil { - jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" - return shim.Error(jsonResp) - } - - jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" - fmt.Printf("Query Response:%s\n", jsonResp) - return shim.Success(Avalbytes) -} - -func main() { - err := shim.Start(new(SimpleChaincode)) - if err != nil { - fmt.Printf("Error starting Simple chaincode: %s", err) - } -} +// import ( +// "fmt" +// "strconv" + +// "github.com/hyperledger/fabric/core/chaincode/shim" +// pb "github.com/hyperledger/fabric/protos/peer" +// ) + +// // SimpleChaincode example simple Chaincode implementation +// type SimpleChaincode struct { +// } + +// // Init implement Chaincode +// func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { +// fmt.Println("ex02 Init") +// _, args := stub.GetFunctionAndParameters() +// var A, B string // Entities +// var Aval, Bval int // Asset holdings +// var err error + +// if len(args) != 4 { +// return shim.Error("Incorrect number of arguments. Expecting 4") +// } + +// // Initialize the chaincode +// A = args[0] +// Aval, err = strconv.Atoi(args[1]) +// if err != nil { +// return shim.Error("Expecting integer value for asset holding") +// } +// B = args[2] +// Bval, err = strconv.Atoi(args[3]) +// if err != nil { +// return shim.Error("Expecting integer value for asset holding") +// } +// fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) + +// // Write the state to the ledger +// err = stub.PutState(A, []byte(strconv.Itoa(Aval))) +// if err != nil { +// return shim.Error(err.Error()) +// } + +// err = stub.PutState(B, []byte(strconv.Itoa(Bval))) +// if err != nil { +// return shim.Error(err.Error()) +// } + +// return shim.Success(nil) +// } + +// // Invoke implement Chaincode +// func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { +// fmt.Println("ex02 Invoke") +// function, args := stub.GetFunctionAndParameters() +// if function == "invoke" { +// // Make payment of X units from A to B +// return t.invoke(stub, args) +// } else if function == "delete" { +// // Deletes an entity from its state +// return t.delete(stub, args) +// } else if function == "query" { +// // the old "Query" is now implemtned in invoke +// return t.query(stub, args) +// } + +// return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"") +// } + +// // Transaction makes payment of X units from A to B +// func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { +// var A, B string // Entities +// var Aval, Bval int // Asset holdings +// var X int // Transaction value +// var err error + +// if len(args) != 3 { +// return shim.Error("Incorrect number of arguments. Expecting 3") +// } + +// A = args[0] +// B = args[1] + +// // Get the state from the ledger +// // TODO: will be nice to have a GetAllState call to ledger +// Avalbytes, err := stub.GetState(A) +// if err != nil { +// return shim.Error("Failed to get state") +// } +// if Avalbytes == nil { +// return shim.Error("Entity not found") +// } +// Aval, _ = strconv.Atoi(string(Avalbytes)) + +// Bvalbytes, err := stub.GetState(B) +// if err != nil { +// return shim.Error("Failed to get state") +// } +// if Bvalbytes == nil { +// return shim.Error("Entity not found") +// } +// Bval, _ = strconv.Atoi(string(Bvalbytes)) + +// // Perform the execution +// X, err = strconv.Atoi(args[2]) +// if err != nil { +// return shim.Error("Invalid transaction amount, expecting a integer value") +// } +// Aval = Aval - X +// Bval = Bval + X +// fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) + +// // Write the state back to the ledger +// err = stub.PutState(A, []byte(strconv.Itoa(Aval))) +// if err != nil { +// return shim.Error(err.Error()) +// } + +// err = stub.PutState(B, []byte(strconv.Itoa(Bval))) +// if err != nil { +// return shim.Error(err.Error()) +// } + +// return shim.Success(nil) +// } + +// // Deletes an entity from state +// func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { +// if len(args) != 1 { +// return shim.Error("Incorrect number of arguments. Expecting 1") +// } + +// A := args[0] + +// // Delete the key from the state in ledger +// err := stub.DelState(A) +// if err != nil { +// return shim.Error("Failed to delete state") +// } + +// return shim.Success(nil) +// } + +// // query callback representing the query of a chaincode +// func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { +// var A string // Entities +// var err error + +// if len(args) != 1 { +// return shim.Error("Incorrect number of arguments. Expecting name of the person to query") +// } + +// A = args[0] + +// // Get the state from the ledger +// Avalbytes, err := stub.GetState(A) +// if err != nil { +// jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" +// return shim.Error(jsonResp) +// } + +// if Avalbytes == nil { +// jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" +// return shim.Error(jsonResp) +// } + +// jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" +// fmt.Printf("Query Response:%s\n", jsonResp) +// return shim.Success(Avalbytes) +// } + +// func main() { +// err := shim.Start(new(SimpleChaincode)) +// if err != nil { +// fmt.Printf("Error starting Simple chaincode: %s", err) +// } +// } diff --git a/core/controller/worker/local.go b/core/controller/worker/local.go index b51c0d5..1393967 100644 --- a/core/controller/worker/local.go +++ b/core/controller/worker/local.go @@ -7,6 +7,7 @@ import ( "time" fcom "github.com/meshplus/hyperbench-common/common" + "github.com/op/go-logging" "github.com/meshplus/hyperbench/core/collector" "github.com/meshplus/hyperbench/core/engine" @@ -17,6 +18,7 @@ import ( // LocalWorker is the local Worker implement type LocalWorker struct { + logger *logging.Logger conf LocalWorkerConfig eg engine.Engine pool vmpool.Pool @@ -37,6 +39,7 @@ type LocalWorkerConfig struct { Cap int64 Rate int64 Duration time.Duration + Accounts int64 } // NewLocalWorker create LocalWorker. @@ -44,6 +47,7 @@ func NewLocalWorker(config LocalWorkerConfig) (*LocalWorker, error) { blockchain.InitPlugin() localWorker := LocalWorker{ + logger: fcom.GetLogger("worker"), collector: collector.NewTDigestSummaryCollector(), resultCh: make(chan *fcom.Result, 1024), done: make(chan struct{}), @@ -58,14 +62,13 @@ func NewLocalWorker(config LocalWorkerConfig) (*LocalWorker, error) { }) // init vm pool - pool, err := vmpool.NewPoolImpl(config.Index, config.Cap) + pool, err := vmpool.NewPoolImpl(config.Index, config.Cap, config.Accounts) if err != nil { return nil, err } // init index idx := fcom.TxIndex{ - EngineIdx: config.Index, TxIdx: -1, MissIdx: 0, } @@ -96,12 +99,19 @@ func (l *LocalWorker) SetContext(bs []byte) (err error) { // BeforeRun call user hook func (l *LocalWorker) BeforeRun() (err error) { + wg := &sync.WaitGroup{} l.pool.Walk(func(v vm.VM) bool { - if err = v.BeforeRun(); err != nil { - return true - } + wg.Add(1) + go func() { + if err = v.BeforeRun(); err != nil { + l.logger.Errorf("Before run error: %s", err) + } + wg.Done() + }() + return false }) + wg.Wait() return err } @@ -117,12 +127,19 @@ func (l *LocalWorker) Do() error { // AfterRun call user hook func (l *LocalWorker) AfterRun() (err error) { + wg := &sync.WaitGroup{} l.pool.Walk(func(v vm.VM) bool { - if err = v.AfterRun(); err != nil { - return true - } + wg.Add(1) + go func() { + if err = v.AfterRun(); err != nil { + l.logger.Errorf("After run error: %s", err) + } + wg.Done() + }() + return false }) + wg.Wait() return err } @@ -190,7 +207,6 @@ func (l *LocalWorker) asyncJob() { } func (l *LocalWorker) atomicAddIndex() (idx fcom.TxIndex) { - idx.EngineIdx = atomic.LoadInt64(&l.idx.EngineIdx) idx.TxIdx = atomic.AddInt64(&l.idx.TxIdx, 1) return } diff --git a/core/controller/worker/worker.go b/core/controller/worker/worker.go index b281803..8937ede 100644 --- a/core/controller/worker/worker.go +++ b/core/controller/worker/worker.go @@ -60,9 +60,10 @@ func NewWorkers() (workers []Worker, err error) { Cap: viper.GetInt64(fcom.EngineCapPath), Rate: viper.GetInt64(fcom.EngineRatePath), Duration: viper.GetDuration(fcom.EngineDurationPath), + Accounts: viper.GetInt64(fcom.EngineAccountsPath), }) if err != nil { - return nil, ErrConfig + return nil, errors.Wrap(err, ErrConfig.Error()) } workers = []Worker{ localWorker, diff --git a/core/controller/worker/worker_test.go b/core/controller/worker/worker_test.go index 324f157..8a386c8 100644 --- a/core/controller/worker/worker_test.go +++ b/core/controller/worker/worker_test.go @@ -13,7 +13,7 @@ import ( ) func TestLocalWorker(t *testing.T) { - localWorker, err := NewLocalWorker(LocalWorkerConfig{0, 5, 20, time.Second * 5}) + localWorker, err := NewLocalWorker(LocalWorkerConfig{0, 5, 20, time.Second * 5, 100}) assert.NoError(t, err) assert.NotNil(t, localWorker) @@ -45,7 +45,7 @@ func TestLocalWorker(t *testing.T) { localWorker.Done() localWorker.Teardown() - l, _ := NewLocalWorker(LocalWorkerConfig{0, 5, 20, time.Second * 3}) + l, _ := NewLocalWorker(LocalWorkerConfig{0, 5, 20, time.Second * 3, 100}) l.Do() l.cancel() time.Sleep(time.Second * 4) diff --git a/core/network/server/server.go b/core/network/server/server.go index ef9c353..d1592ad 100644 --- a/core/network/server/server.go +++ b/core/network/server/server.go @@ -164,6 +164,7 @@ func (s *Server) Start() error { Cap: int64(viper.GetInt(fcom.EngineCapPath) / l), Rate: int64(viper.GetInt(fcom.EngineRatePath) / l), Duration: viper.GetDuration(fcom.EngineDurationPath), + Accounts: int64(viper.GetInt(fcom.EngineAccountsPath) / l), }) if err != nil { diff --git a/core/vmpool/vmpool.go b/core/vmpool/vmpool.go index 91b90bc..4a42d24 100644 --- a/core/vmpool/vmpool.go +++ b/core/vmpool/vmpool.go @@ -35,22 +35,24 @@ type PoolImpl struct { } // NewPoolImpl create PoolImpl. -func NewPoolImpl(workerID int64, cap int64) (*PoolImpl, error) { +func NewPoolImpl(workerID int64, cap int64, accounts int64) (*PoolImpl, error) { p := &PoolImpl{ cap: cap, ch: make(chan vm.VM, cap), } scriptPath := viper.GetString(fcom.ClientScriptPath) + engine := viper.GetInt64(fcom.EngineCapPath) t := strings.TrimPrefix(path.Ext(scriptPath), ".") configBase := base.ConfigBase{ Path: scriptPath, Ctx: fcom.VMContext{ WorkerIdx: workerID, VMIdx: 0, + Engine: engine, + Accounts: accounts, }, } - configBase.Ctx.WorkerIdx = workerID var i int64 fcom.GetLogger("pool").Notice(workerID, cap, scriptPath, t) for i = 0; i < cap; i++ { diff --git a/filesystem/filesystem-packr.go b/filesystem/filesystem-packr.go new file mode 100644 index 0000000..6f4ab5f --- /dev/null +++ b/filesystem/filesystem-packr.go @@ -0,0 +1,8 @@ +// +build !skippackr +// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT. + +// You can use the "packr clean" command to clean up this, +// and any other packr generated files. +package filesystem + +import _ "github.com/meshplus/hyperbench/packrd" diff --git a/go.mod b/go.mod index a334e62..7487231 100644 --- a/go.mod +++ b/go.mod @@ -1,39 +1,81 @@ module github.com/meshplus/hyperbench +go 1.20 + +replace github.com/meshplus/hyperbench-common v0.0.0-20220128060413-2f16193421b0 => github.com/axiomesh/hyperbench-common v0.0.0-20230917111010-42203b500fdf + require ( - github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect - github.com/Shopify/sarama v1.26.1 // indirect - github.com/fsouza/go-dockerclient v1.4.4 // indirect + github.com/ethereum/go-ethereum v1.12.0 github.com/gin-gonic/gin v1.7.7 github.com/gobuffalo/packr/v2 v2.8.3 - github.com/golang/snappy v0.0.4 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect - github.com/hashicorp/go-version v1.2.0 // indirect - github.com/hyperledger/fabric v1.4.3 - github.com/hyperledger/fabric-amcl v0.0.0-20190902191507-f66264322317 // indirect github.com/influxdata/tdigest v0.0.1 github.com/json-iterator/go v1.1.12 github.com/meshplus/hyperbench-common v0.0.0-20220128060413-2f16193421b0 github.com/mholt/archiver/v3 v3.5.0 - github.com/miekg/pkcs11 v1.0.3 // indirect - github.com/mitchellh/mapstructure v1.4.3 - github.com/onsi/ginkgo v1.14.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/pingcap/failpoint v0.0.0-20191029060244-12f4ac2fd11d github.com/pkg/errors v0.9.1 - github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/spf13/cast v1.4.1 github.com/spf13/cobra v1.3.0 github.com/spf13/viper v1.10.1 - github.com/stretchr/testify v1.7.0 - github.com/sykesm/zap-logfmt v0.0.2 // indirect + github.com/stretchr/testify v1.8.2 github.com/xuperchain/contract-sdk-go v1.0.0 github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583 - golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect - golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect - golang.org/x/tools v0.1.9 // indirect - gonum.org/v1/gonum v0.6.0 // indirect ) -go 1.13 - +require ( + github.com/andybalholm/brotli v1.0.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/dsnet/compress v0.0.1 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.13.0 // indirect + github.com/go-playground/universal-translator v0.17.0 // indirect + github.com/go-playground/validator/v10 v10.6.1 // indirect + github.com/gobuffalo/logger v1.0.6 // indirect + github.com/gobuffalo/packd v1.0.1 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/karrick/godirwalk v1.16.1 // indirect + github.com/klauspost/compress v1.15.15 // indirect + github.com/klauspost/pgzip v1.2.4 // indirect + github.com/leodido/go-urn v1.2.0 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/markbates/errx v1.1.0 // indirect + github.com/markbates/oncer v1.0.0 // indirect + github.com/markbates/safe v1.0.1 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nwaples/rardecode v1.1.0 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pierrec/lz4/v4 v4.0.3 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + github.com/ugorji/go/codec v1.1.7 // indirect + github.com/ulikunitz/xz v0.5.7 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + golang.org/x/crypto v0.1.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect + google.golang.org/grpc v1.43.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index bfab4e3..0000000 --- a/package-lock.json +++ /dev/null @@ -1,2114 +0,0 @@ -{ - "name": "frigate", - "version": "1.0.2", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "JSONStream": { - "version": "1.3.2", - "resolved": "http://registry.npm.taobao.org/JSONStream/download/JSONStream-1.3.2.tgz", - "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "align-text": { - "version": "0.1.4", - "resolved": "http://registry.npm.taobao.org/align-text/download/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "http://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "http://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/array-find-index/download/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-ify": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/array-ify/download/array-ify-1.0.0.tgz", - "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/arrify/download/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "http://registry.npm.taobao.org/async/download/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "http://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz", - "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/buffer-from/download/buffer-from-1.0.0.tgz", - "integrity": "sha1-TLiDLSNhJYmwQG6eKVbBfwb99TE=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "http://registry.npm.taobao.org/builtin-modules/download/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, - "optional": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "http://registry.npm.taobao.org/camelcase-keys/download/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - }, - "center-align": { - "version": "0.1.3", - "resolved": "http://registry.npm.taobao.org/center-align/download/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cliui": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/cliui/download/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "http://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true, - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "colors": { - "version": "0.6.2", - "resolved": "http://registry.npm.taobao.org/colors/download/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", - "dev": true - }, - "commander": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/commander/download/commander-2.1.0.tgz", - "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=", - "dev": true - }, - "compare-func": { - "version": "1.3.2", - "resolved": "http://registry.npm.taobao.org/compare-func/download/compare-func-1.3.2.tgz", - "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^3.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "http://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "http://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz", - "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "conventional-changelog": { - "version": "1.1.24", - "resolved": "http://registry.npm.taobao.org/conventional-changelog/download/conventional-changelog-1.1.24.tgz", - "integrity": "sha1-PZTCnJYPUmHAAmeDFbdWzdPX0fA=", - "dev": true, - "requires": { - "conventional-changelog-angular": "^1.6.6", - "conventional-changelog-atom": "^0.2.8", - "conventional-changelog-codemirror": "^0.3.8", - "conventional-changelog-core": "^2.0.11", - "conventional-changelog-ember": "^0.3.12", - "conventional-changelog-eslint": "^1.0.9", - "conventional-changelog-express": "^0.3.6", - "conventional-changelog-jquery": "^0.1.0", - "conventional-changelog-jscs": "^0.1.0", - "conventional-changelog-jshint": "^0.3.8", - "conventional-changelog-preset-loader": "^1.1.8" - } - }, - "conventional-changelog-angular": { - "version": "1.6.6", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-angular/download/conventional-changelog-angular-1.6.6.tgz", - "integrity": "sha1-sn8rMVwW0KHyPrGBMJ0OakaY6g8=", - "dev": true, - "requires": { - "compare-func": "^1.3.1", - "q": "^1.5.1" - } - }, - "conventional-changelog-atom": { - "version": "0.2.8", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-atom/download/conventional-changelog-atom-0.2.8.tgz", - "integrity": "sha1-gDdpNFWZDjJW8pcyCkX6R+5VOhQ=", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-codemirror": { - "version": "0.3.8", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-codemirror/download/conventional-changelog-codemirror-0.3.8.tgz", - "integrity": "sha1-oZgsgpH07k1vL2KBfGsuzSxLe0c=", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-core": { - "version": "2.0.11", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-core/download/conventional-changelog-core-2.0.11.tgz", - "integrity": "sha1-GbX71VqWl3c+1mYfTjIDDtfjAoc=", - "dev": true, - "requires": { - "conventional-changelog-writer": "^3.0.9", - "conventional-commits-parser": "^2.1.7", - "dateformat": "^3.0.0", - "get-pkg-repo": "^1.0.0", - "git-raw-commits": "^1.3.6", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^1.3.6", - "lodash": "^4.2.1", - "normalize-package-data": "^2.3.5", - "q": "^1.5.1", - "read-pkg": "^1.1.0", - "read-pkg-up": "^1.0.1", - "through2": "^2.0.0" - } - }, - "conventional-changelog-ember": { - "version": "0.3.12", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-ember/download/conventional-changelog-ember-0.3.12.tgz", - "integrity": "sha1-t9MYUXVtD8tJsDHf/ravqTsgJAA=", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-eslint": { - "version": "1.0.9", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-eslint/download/conventional-changelog-eslint-1.0.9.tgz", - "integrity": "sha1-sTzH5LRyyBlFDt4DH/GnXA49B9M=", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-express": { - "version": "0.3.6", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-express/download/conventional-changelog-express-0.3.6.tgz", - "integrity": "sha1-SmKVyxF4UFn7CSAhgNDlnDWLnCw=", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-jquery": { - "version": "0.1.0", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-jquery/download/conventional-changelog-jquery-0.1.0.tgz", - "integrity": "sha1-Agg5cWLjhGmG5xJztsecW1+A9RA=", - "dev": true, - "requires": { - "q": "^1.4.1" - } - }, - "conventional-changelog-jscs": { - "version": "0.1.0", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-jscs/download/conventional-changelog-jscs-0.1.0.tgz", - "integrity": "sha1-BHnrRDzH1yxYvwvPDvHURKkvDlw=", - "dev": true, - "requires": { - "q": "^1.4.1" - } - }, - "conventional-changelog-jshint": { - "version": "0.3.8", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-jshint/download/conventional-changelog-jshint-0.3.8.tgz", - "integrity": "sha1-kFHBrAdnq69iox900v6HkOisxsg=", - "dev": true, - "requires": { - "compare-func": "^1.3.1", - "q": "^1.5.1" - } - }, - "conventional-changelog-preset-loader": { - "version": "1.1.8", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-preset-loader/download/conventional-changelog-preset-loader-1.1.8.tgz", - "integrity": "sha1-QLsPFCzSfRaDnsbHTujbQYCZs3M=", - "dev": true - }, - "conventional-changelog-writer": { - "version": "3.0.9", - "resolved": "http://registry.npm.taobao.org/conventional-changelog-writer/download/conventional-changelog-writer-3.0.9.tgz", - "integrity": "sha1-Suzf7zP/KlO7DPO4BxziHw6ZRjQ=", - "dev": true, - "requires": { - "compare-func": "^1.3.1", - "conventional-commits-filter": "^1.1.6", - "dateformat": "^3.0.0", - "handlebars": "^4.0.2", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.2.1", - "meow": "^4.0.0", - "semver": "^5.5.0", - "split": "^1.0.0", - "through2": "^2.0.0" - } - }, - "conventional-commit-types": { - "version": "2.2.0", - "resolved": "http://registry.npm.taobao.org/conventional-commit-types/download/conventional-commit-types-2.2.0.tgz", - "integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=", - "dev": true - }, - "conventional-commits-filter": { - "version": "1.1.6", - "resolved": "http://registry.npm.taobao.org/conventional-commits-filter/download/conventional-commits-filter-1.1.6.tgz", - "integrity": "sha1-Q4nNjlj+iXUMC1+1jx1/DMitODE=", - "dev": true, - "requires": { - "is-subset": "^0.1.1", - "modify-values": "^1.0.0" - } - }, - "conventional-commits-parser": { - "version": "2.1.7", - "resolved": "http://registry.npm.taobao.org/conventional-commits-parser/download/conventional-commits-parser-2.1.7.tgz", - "integrity": "sha1-7KRe1hQNcrqXIu5BMmdNY55kTo4=", - "dev": true, - "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.0", - "lodash": "^4.2.1", - "meow": "^4.0.0", - "split2": "^2.0.0", - "through2": "^2.0.0", - "trim-off-newlines": "^1.0.0" - } - }, - "conventional-recommended-bump": { - "version": "1.2.1", - "resolved": "http://registry.npm.taobao.org/conventional-recommended-bump/download/conventional-recommended-bump-1.2.1.tgz", - "integrity": "sha1-G3E377UJH5n+AJ4v6d23zEkOk3U=", - "dev": true, - "requires": { - "concat-stream": "^1.4.10", - "conventional-commits-filter": "^1.1.1", - "conventional-commits-parser": "^2.1.1", - "git-raw-commits": "^1.3.0", - "git-semver-tags": "^1.3.0", - "meow": "^3.3.0", - "object-assign": "^4.0.1" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/camelcase-keys/download/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "indent-string": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/indent-string/download/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "map-obj": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/map-obj/download/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "http://registry.npm.taobao.org/meow/download/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "redent": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/redent/download/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/strip-indent/download/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/trim-newlines/download/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "http://registry.npm.taobao.org/cross-spawn/download/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "http://registry.npm.taobao.org/currently-unhandled/download/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "cz-conventional-changelog": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/cz-conventional-changelog/download/cz-conventional-changelog-2.1.0.tgz", - "integrity": "sha1-L0vHOQ4yROTfKT5ro1Hkx0Cnx2Q=", - "dev": true, - "requires": { - "conventional-commit-types": "^2.0.0", - "lodash.map": "^4.5.1", - "longest": "^1.0.1", - "right-pad": "^1.0.1", - "word-wrap": "^1.0.3" - } - }, - "dargs": { - "version": "4.1.0", - "resolved": "http://registry.npm.taobao.org/dargs/download/dargs-4.1.0.tgz", - "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "dateformat": { - "version": "3.0.3", - "resolved": "http://registry.npm.taobao.org/dateformat/download/dateformat-3.0.3.tgz", - "integrity": "sha1-puN0maTZqc+F71hyBE1ikByYia4=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decamelize-keys": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/decamelize-keys/download/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/map-obj/download/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - } - } - }, - "dot-prop": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/dot-prop/download/dot-prop-3.0.0.tgz", - "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotgitignore": { - "version": "1.0.3", - "resolved": "http://registry.npm.taobao.org/dotgitignore/download/dotgitignore-1.0.3.tgz", - "integrity": "sha1-pELL3n3CDf9RzbhJ5MWmRWjAeSM=", - "dev": true, - "requires": { - "find-up": "^2.1.0", - "minimatch": "^3.0.4" - } - }, - "error-ex": { - "version": "1.3.1", - "resolved": "http://registry.npm.taobao.org/error-ex/download/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "http://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "execa": { - "version": "0.7.0", - "resolved": "http://registry.npm.taobao.org/execa/download/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "http://registry.npm.taobao.org/figures/download/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/find-up/download/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "findup": { - "version": "0.1.5", - "resolved": "http://registry.npm.taobao.org/findup/download/findup-0.1.5.tgz", - "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=", - "dev": true, - "requires": { - "colors": "~0.6.0-1", - "commander": "~2.1.0" - } - }, - "fs-access": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/fs-access/download/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", - "dev": true, - "requires": { - "null-check": "^1.0.0" - } - }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/get-caller-file/download/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true - }, - "get-pkg-repo": { - "version": "1.4.0", - "resolved": "http://registry.npm.taobao.org/get-pkg-repo/download/get-pkg-repo-1.4.0.tgz", - "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "meow": "^3.3.0", - "normalize-package-data": "^2.3.0", - "parse-github-repo-url": "^1.3.0", - "through2": "^2.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/camelcase-keys/download/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "indent-string": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/indent-string/download/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "map-obj": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/map-obj/download/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "http://registry.npm.taobao.org/meow/download/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "redent": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/redent/download/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/strip-indent/download/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/trim-newlines/download/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - } - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "http://registry.npm.taobao.org/get-stdin/download/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/get-stream/download/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "ghooks": { - "version": "2.0.3", - "resolved": "http://registry.npm.taobao.org/ghooks/download/ghooks-2.0.3.tgz", - "integrity": "sha1-vXySV6yuPyYWw3ecRUfTdTfLBQU=", - "dev": true, - "requires": { - "findup": "0.1.5", - "lodash.clone": "4.5.0", - "manage-path": "2.0.0", - "opt-cli": "1.5.1", - "path-exists": "3.0.0", - "spawn-command": "0.0.2" - } - }, - "git-raw-commits": { - "version": "1.3.6", - "resolved": "http://registry.npm.taobao.org/git-raw-commits/download/git-raw-commits-1.3.6.tgz", - "integrity": "sha1-J8NaMqZ3d8Hs1BKiOabBnXG5Wv8=", - "dev": true, - "requires": { - "dargs": "^4.0.1", - "lodash.template": "^4.0.2", - "meow": "^4.0.0", - "split2": "^2.0.0", - "through2": "^2.0.0" - } - }, - "git-remote-origin-url": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/git-remote-origin-url/download/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", - "dev": true, - "requires": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "git-semver-tags": { - "version": "1.3.6", - "resolved": "http://registry.npm.taobao.org/git-semver-tags/download/git-semver-tags-1.3.6.tgz", - "integrity": "sha1-NX6gH3KAeU/gkn8oBr7mQU0sq6U=", - "dev": true, - "requires": { - "meow": "^4.0.0", - "semver": "^5.5.0" - } - }, - "gitconfiglocal": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/gitconfiglocal/download/gitconfiglocal-1.0.0.tgz", - "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", - "dev": true, - "requires": { - "ini": "^1.3.2" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "http://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/graceful-readlink/download/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "handlebars": { - "version": "4.0.11", - "resolved": "http://registry.npm.taobao.org/handlebars/download/handlebars-4.0.11.tgz", - "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", - "dev": true, - "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/has-ansi/download/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "hosted-git-info": { - "version": "2.6.0", - "resolved": "http://registry.npm.taobao.org/hosted-git-info/download/hosted-git-info-2.6.0.tgz", - "integrity": "sha1-IyNbKasjDFdqqw1PE/wEawsDgiI=", - "dev": true - }, - "indent-string": { - "version": "3.2.0", - "resolved": "http://registry.npm.taobao.org/indent-string/download/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "inherits": { - "version": "2.0.3", - "resolved": "http://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "http://registry.npm.taobao.org/ini/download/ini-1.3.5.tgz", - "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/invert-kv/download/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "http://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "http://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz", - "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", - "dev": true, - "optional": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/is-builtin-module/download/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-finite": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/is-finite/download/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-subset": { - "version": "0.1.1", - "resolved": "http://registry.npm.taobao.org/is-subset/download/is-subset-0.1.1.tgz", - "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", - "dev": true - }, - "is-text-path": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/is-text-path/download/is-text-path-1.0.1.tgz", - "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", - "dev": true, - "requires": { - "text-extensions": "^1.0.0" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "http://registry.npm.taobao.org/is-utf8/download/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/json-parse-better-errors/download/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "http://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "http://registry.npm.taobao.org/jsonparse/download/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "http://registry.npm.taobao.org/lazy-cache/download/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, - "optional": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/lcid/download/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "http://registry.npm.taobao.org/load-json-file/download/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/locate-path/download/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.5", - "resolved": "http://registry.npm.taobao.org/lodash/download/lodash-4.17.5.tgz", - "integrity": "sha1-maktZcAnLevoyWtgV7yPv6O+1RE=", - "dev": true - }, - "lodash._baseclone": { - "version": "4.5.7", - "resolved": "http://registry.npm.taobao.org/lodash._baseclone/download/lodash._baseclone-4.5.7.tgz", - "integrity": "sha1-zkKt4IOE711i+nfDD2GkbmhvhDQ=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "http://registry.npm.taobao.org/lodash.clone/download/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.map": { - "version": "4.6.0", - "resolved": "http://registry.npm.taobao.org/lodash.map/download/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", - "dev": true - }, - "lodash.template": { - "version": "4.4.0", - "resolved": "http://registry.npm.taobao.org/lodash.template/download/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "dev": true, - "requires": { - "lodash._reinterpolate": "~3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "http://registry.npm.taobao.org/lodash.templatesettings/download/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", - "dev": true, - "requires": { - "lodash._reinterpolate": "~3.0.0" - } - }, - "longest": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/longest/download/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "http://registry.npm.taobao.org/loud-rejection/download/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.2", - "resolved": "http://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.2.tgz", - "integrity": "sha1-RSNLLm4vKzPaElYkxGZJKaAiTD8=", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "manage-path": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/manage-path/download/manage-path-2.0.0.tgz", - "integrity": "sha1-9M+EV7km7u4qg7FzUBQUvHbrlZc=", - "dev": true - }, - "map-obj": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/map-obj/download/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "mem": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/mem/download/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "meow": { - "version": "4.0.0", - "resolved": "http://registry.npm.taobao.org/meow/download/meow-4.0.0.tgz", - "integrity": "sha1-/VhV3QCNtbksVSCC2xwwfLogsp0=", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/read-pkg/download/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/read-pkg-up/download/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - } - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/mimic-fn/download/mimic-fn-1.2.0.tgz", - "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "http://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "http://registry.npm.taobao.org/minimist/download/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "minimist-options": { - "version": "3.0.2", - "resolved": "http://registry.npm.taobao.org/minimist-options/download/minimist-options-3.0.2.tgz", - "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" - } - }, - "modify-values": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/modify-values/download/modify-values-1.0.0.tgz", - "integrity": "sha1-4rbN65zhn5kxelNyLz2/XfXqqrI=", - "dev": true - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "http://registry.npm.taobao.org/normalize-package-data/download/normalize-package-data-2.4.0.tgz", - "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "http://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "null-check": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/null-check/download/null-check-1.0.0.tgz", - "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "http://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "opt-cli": { - "version": "1.5.1", - "resolved": "http://registry.npm.taobao.org/opt-cli/download/opt-cli-1.5.1.tgz", - "integrity": "sha1-BNtEexPJa5kusxaFJm9O0NlzbcI=", - "dev": true, - "requires": { - "commander": "2.9.0", - "lodash.clone": "4.3.2", - "manage-path": "2.0.0", - "spawn-command": "0.0.2-1" - }, - "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "http://registry.npm.taobao.org/commander/download/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "lodash.clone": { - "version": "4.3.2", - "resolved": "http://registry.npm.taobao.org/lodash.clone/download/lodash.clone-4.3.2.tgz", - "integrity": "sha1-5WsXa2gjp93jj38r9Y3n1ZcSAOk=", - "dev": true, - "requires": { - "lodash._baseclone": "~4.5.0" - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "http://registry.npm.taobao.org/spawn-command/download/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - } - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "http://registry.npm.taobao.org/optimist/download/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-locale": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/os-locale/download/os-locale-2.1.0.tgz", - "integrity": "sha1-QrwpAKa1uL0XN2yOiCtlr8zyS/I=", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/p-finally/download/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/p-limit/download/p-limit-1.2.0.tgz", - "integrity": "sha1-DpK2vty1nwIsE9DxlJ3ILRWQnxw=", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/p-locate/download/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/p-try/download/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-github-repo-url": { - "version": "1.4.1", - "resolved": "http://registry.npm.taobao.org/parse-github-repo-url/download/parse-github-repo-url-1.4.1.tgz", - "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "http://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "http://registry.npm.taobao.org/path-key/download/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz", - "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "http://registry.npm.taobao.org/pinkie/download/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "http://registry.npm.taobao.org/pinkie-promise/download/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.0.tgz", - "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/pseudomap/download/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "http://registry.npm.taobao.org/q/download/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "quick-lru": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/quick-lru/download/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/read-pkg/download/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/load-json-file/download/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "http://registry.npm.taobao.org/parse-json/download/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/path-type/download/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/strip-bom/download/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/read-pkg-up/download/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "http://registry.npm.taobao.org/find-up/download/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/path-exists/download/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.6.tgz", - "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/redent/download/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "http://registry.npm.taobao.org/repeat-string/download/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "optional": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "http://registry.npm.taobao.org/repeating/download/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "http://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/require-main-filename/download/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "right-align": { - "version": "0.1.3", - "resolved": "http://registry.npm.taobao.org/right-align/download/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, - "right-pad": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/right-pad/download/right-pad-1.0.1.tgz", - "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.1.tgz", - "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", - "dev": true - }, - "semver": { - "version": "5.5.0", - "resolved": "http://registry.npm.taobao.org/semver/download/semver-5.5.0.tgz", - "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", - "dev": true - }, - "semver-regex": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/semver-regex/download/semver-regex-1.0.0.tgz", - "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "http://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "http://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "source-map": { - "version": "0.4.4", - "resolved": "http://registry.npm.taobao.org/source-map/download/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "spawn-command": { - "version": "0.0.2", - "resolved": "http://registry.npm.taobao.org/spawn-command/download/spawn-command-0.0.2.tgz", - "integrity": "sha1-lUThpDygRfhTGqwaSMspva5iM44=", - "dev": true - }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/spdx-correct/download/spdx-correct-3.0.0.tgz", - "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/spdx-exceptions/download/spdx-exceptions-2.1.0.tgz", - "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/spdx-expression-parse/download/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/spdx-license-ids/download/spdx-license-ids-3.0.0.tgz", - "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=", - "dev": true - }, - "split": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/split/download/split-1.0.1.tgz", - "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", - "dev": true, - "requires": { - "through": "2" - } - }, - "split2": { - "version": "2.2.0", - "resolved": "http://registry.npm.taobao.org/split2/download/split2-2.2.0.tgz", - "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", - "dev": true, - "requires": { - "through2": "^2.0.2" - } - }, - "standard-version": { - "version": "4.3.0", - "resolved": "http://registry.npm.taobao.org/standard-version/download/standard-version-4.3.0.tgz", - "integrity": "sha1-QQBs/uTuq3wP86R+7KpMdQbtLj8=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "conventional-changelog": "^1.1.0", - "conventional-recommended-bump": "^1.0.0", - "dotgitignore": "^1.0.3", - "figures": "^1.5.0", - "fs-access": "^1.0.0", - "semver": "^5.1.0", - "yargs": "^8.0.1" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "http://registry.npm.taobao.org/string-width/download/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "http://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "http://registry.npm.taobao.org/strip-bom/download/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/strip-eof/download/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/strip-indent/download/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "text-extensions": { - "version": "1.7.0", - "resolved": "http://registry.npm.taobao.org/text-extensions/download/text-extensions-1.7.0.tgz", - "integrity": "sha1-+qq6JiXtdG1WiiPk0KrNm/CKizk=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npm.taobao.org/through/download/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "http://registry.npm.taobao.org/through2/download/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } - }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/trim-newlines/download/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - }, - "trim-off-newlines": { - "version": "1.0.1", - "resolved": "http://registry.npm.taobao.org/trim-off-newlines/download/trim-off-newlines-1.0.1.tgz", - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "http://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "http://registry.npm.taobao.org/uglify-js/download/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "optional": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "http://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "http://registry.npm.taobao.org/yargs/download/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/uglify-to-browserify/download/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "validate-commit-msg-smart": { - "version": "1.1.2", - "resolved": "http://registry.npm.taobao.org/validate-commit-msg-smart/download/validate-commit-msg-smart-1.1.2.tgz", - "integrity": "sha1-og3j06UKXl1ePmXsuZos2agmIio=", - "dev": true, - "requires": { - "findup": "0.1.5", - "semver-regex": "1.0.0" - } - }, - "validate-npm-package-license": { - "version": "3.0.3", - "resolved": "http://registry.npm.taobao.org/validate-npm-package-license/download/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha1-gWQ7y+8b3+zUYjeT3EZIlIupgzg=", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.3.0", - "resolved": "http://registry.npm.taobao.org/which/download/which-1.3.0.tgz", - "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "window-size": { - "version": "0.1.0", - "resolved": "http://registry.npm.taobao.org/window-size/download/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true, - "optional": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "http://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz", - "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "http://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "http://registry.npm.taobao.org/xtend/download/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "http://registry.npm.taobao.org/y18n/download/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "http://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "8.0.2", - "resolved": "http://registry.npm.taobao.org/yargs/download/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "http://registry.npm.taobao.org/cliui/download/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/load-json-file/download/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "http://registry.npm.taobao.org/parse-json/download/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/path-type/download/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/read-pkg/download/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/read-pkg-up/download/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - } - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "http://registry.npm.taobao.org/yargs-parser/download/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 0f30f1e..0000000 --- a/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "frigate", - "version": "1.0.2", - "description": "frigate is the performance test tool for hyperchain", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "release": "standard-version" - }, - "repository": { - "type": "git", - "url": "git.hyperchain.cn/hyperchain/hyperchain" - }, - "keywords": [ - "blockchain", - "hyperchain" - ], - "author": "Hyperchain Authors", - "license": "Apache-2.0", - "devDependencies": { - "cz-conventional-changelog": "^2.1.0", - "ghooks": "^2.0.2", - "standard-version": "^4.3.0", - "validate-commit-msg-smart": "^1.1.2" - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - }, - "ghooks": { - "commit-msg": "validate-commit-msg", - "pre-commit": "./.githooks/pre-commit" - }, - "validate-commit-msg": { - "types": [ - "feat", - "fix", - "revert", - "chore", - "docs", - "style", - "refactor", - "perf", - "test", - "build", - "ci" - ], - "warnOnFail": false, - "maxSubjectLength": 100, - "subjectPattern": ".+", - "subjectPatternErrorMsg": "subject does not match subject pattern, you should use one of [feat| fix| revert|chore| docs| style| refactor| perf| test| build| ci]", - "helpMessage": "" - } - } -} diff --git a/plugins/index/index.go b/plugins/index/index.go index abe771f..e887cd7 100644 --- a/plugins/index/index.go +++ b/plugins/index/index.go @@ -2,8 +2,9 @@ package index // Index is the Unique Identification of calling `vm.Run` type Index struct { - Worker int64 `mapstructure:"worker"` - VM int64 `mapstructure:"vm"` - Engine int64 `mapstructure:"engine"` - Tx int64 `mapstructure:"tx"` + Worker int64 `mapstructure:"worker"` + VM int64 `mapstructure:"vm"` + Engine int64 `mapstructure:"engine"` + Tx int64 `mapstructure:"tx"` + Accounts int64 `mapstructure:"accounts"` } diff --git a/vm/lua/glua/blockchain.go b/vm/lua/glua/blockchain.go index 6a20833..65000ec 100644 --- a/vm/lua/glua/blockchain.go +++ b/vm/lua/glua/blockchain.go @@ -1,6 +1,8 @@ package glua import ( + "fmt" + fcom "github.com/meshplus/hyperbench-common/common" lua "github.com/yuin/gopher-lua" ) @@ -16,6 +18,10 @@ func newBlockchain(L *lua.LState, client fcom.Blockchain) lua.LValue { clientTable.RawSetString("GetContext", getContextLuaFunction(L, client)) clientTable.RawSetString("SetContext", setContextLuaFunction(L, client)) clientTable.RawSetString("ResetContext", resetContextLuaFunction(L, client)) + clientTable.RawSetString("GetRandomAccountByGroup", getRandomAccountByGroupLuaFunction(L, client)) + clientTable.RawSetString("GetRandomAccount", getRandomAccountLuaFunction(L, client)) + clientTable.RawSetString("GetAccount", getAccountLuaFunction(L, client)) + clientTable.RawSetString("GetContractAddrByName", getContractAddrByNameLuaFunction(L, client)) //clientTable.RawSetString("Statistic",nil) return clientTable } @@ -62,6 +68,42 @@ func resetContextLuaFunction(L *lua.LState, client fcom.Blockchain) lua.LValue { }) } +func getRandomAccountByGroupLuaFunction(L *lua.LState, client fcom.Blockchain) lua.LValue { + return L.NewFunction(func(state *lua.LState) int { + account := client.GetRandomAccountByGroup() + state.Push(lua.LString(account)) + return 1 + }) +} + +func getRandomAccountLuaFunction(L *lua.LState, client fcom.Blockchain) lua.LValue { + return L.NewFunction(func(state *lua.LState) int { + firstArgIndex := 1 + // check first arg is fcom.Blockchain + if checkBlockChainByIdx(state, 1) { + firstArgIndex++ + } + text := state.CheckString(firstArgIndex) + account := client.GetRandomAccount(text) + state.Push(lua.LString(account)) + return 1 + }) +} + +func getAccountLuaFunction(L *lua.LState, client fcom.Blockchain) lua.LValue { + return L.NewFunction(func(state *lua.LState) int { + firstArgIndex := 1 + // check first arg is fcom.Blockchain + if checkBlockChainByIdx(state, 1) { + firstArgIndex++ + } + index := state.CheckInt64(firstArgIndex) + account := client.GetAccount(uint64(index)) + state.Push(lua.LString(account)) + return 1 + }) +} + func optionLuaFunction(L *lua.LState, client fcom.Blockchain) lua.LValue { return L.NewFunction(func(state *lua.LState) int { var map1 fcom.Option @@ -87,66 +129,74 @@ func optionLuaFunction(L *lua.LState, client fcom.Blockchain) lua.LValue { } func invokeLuaFunction(L *lua.LState, client fcom.Blockchain) *lua.LFunction { - var invoke fcom.Invoke - return blockchainLuaFunction(L, client, invoke, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { - return b.Invoke(b2.(fcom.Invoke), option...) + return L.NewFunction(func(state *lua.LState) int { + var invoke fcom.Invoke + res := blockchainLuaFunction(L, client, invoke, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { + return b.Invoke(b2.(fcom.Invoke), option...) + }) + return res }) } func transferLuaFunction(L *lua.LState, client fcom.Blockchain) *lua.LFunction { - var transfer fcom.Transfer - return blockchainLuaFunction(L, client, transfer, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { - return b.Transfer(b2.(fcom.Transfer), option...) + return L.NewFunction(func(state *lua.LState) int { + var transfer fcom.Transfer + res := blockchainLuaFunction(L, client, transfer, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { + return b.Transfer(b2.(fcom.Transfer), option...) + }) + return res }) } func queryLuaFunction(L *lua.LState, client fcom.Blockchain) *lua.LFunction { - var query fcom.Query - return blockchainLuaFunction(L, client, query, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { - return b.Query(b2.(fcom.Query), option...) + return L.NewFunction(func(state *lua.LState) int { + var query fcom.Query + res := blockchainLuaFunction(L, client, query, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { + return b.Query(b2.(fcom.Query), option...) + }) + return res }) } func confirmLuaFunction(L *lua.LState, client fcom.Blockchain) *lua.LFunction { - var confirm *fcom.Result - return blockchainLuaFunction(L, client, confirm, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { - return b.Confirm(b2.(*fcom.Result), option...) + return L.NewFunction(func(state *lua.LState) int { + var confirm *fcom.Result + res := blockchainLuaFunction(L, client, confirm, func(b fcom.Blockchain, b2 interface{}, option ...fcom.Option) interface{} { + return b.Confirm(b2.(*fcom.Result), option...) + }) + return res }) } -func blockchainLuaFunction(L *lua.LState, cli fcom.Blockchain, arg1Type interface{}, fn func(fcom.Blockchain, interface{}, ...fcom.Option) interface{}) *lua.LFunction { - return L.NewFunction(func(state *lua.LState) int { - // case.blockchain:Invoke() --> first arg is fcom.Blockchain - // case.blockchain.Invoke ----> first arg is normal - firstArgIndex := 1 - // check first arg is fcom.Blockchain - if checkBlockChainByIdx(state, 1) { - firstArgIndex++ - } - invokeTable := state.CheckTable(firstArgIndex) - err := TableLua2GoStruct(invokeTable, &arg1Type) - if err != nil { - state.ArgError(1, "interface. expected") - } - if state.GetTop() == 1+firstArgIndex { - ret := fn(cli, arg1Type) - state.Push(go2Lua(state, ret)) - return 1 - } - var opts []fcom.Option - for i := 1 + firstArgIndex; i <= state.GetTop(); i++ { - table := state.CheckTable(i) - var map1 fcom.Option - err := TableLua2GoStruct(table, &map1) - if err != nil { - state.ArgError(1, "common.Option expected") - } - opts = append(opts, map1) - } - ret := fn(cli, arg1Type, opts...) +func blockchainLuaFunction(state *lua.LState, cli fcom.Blockchain, arg1Type interface{}, fn func(fcom.Blockchain, interface{}, ...fcom.Option) interface{}) int { + firstArgIndex := 1 + // check first arg is fcom.Blockchain + if checkBlockChainByIdx(state, 1) { + firstArgIndex++ + } + invokeTable := state.CheckTable(firstArgIndex) + err := TableLua2GoStruct(invokeTable, &arg1Type) + if err != nil { + state.ArgError(1, fmt.Sprintf("interface. expected, %s", err)) + } + if state.GetTop() == 1+firstArgIndex { + ret := fn(cli, arg1Type) state.Push(go2Lua(state, ret)) return 1 - }) + } + var opts []fcom.Option + for i := 1 + firstArgIndex; i <= state.GetTop(); i++ { + table := state.CheckTable(i) + var map1 fcom.Option + err := TableLua2GoStruct(table, &map1) + if err != nil { + state.ArgError(1, "common.Option expected") + } + opts = append(opts, map1) + } + ret := fn(cli, arg1Type, opts...) + state.Push(go2Lua(state, ret)) + return 1 } func checkBlockChainByIdx(state *lua.LState, idx int) bool { @@ -176,3 +226,16 @@ func deployContractLuaFunction(L *lua.LState, client fcom.Blockchain) *lua.LFunc return 1 }) } + +func getContractAddrByNameLuaFunction(L *lua.LState, client fcom.Blockchain) *lua.LFunction { + return L.NewFunction(func(state *lua.LState) int { + firstArgIndex := 1 + if checkBlockChainByIdx(state, 1) { + firstArgIndex++ + } + text := state.CheckString(firstArgIndex) + addr := client.GetContractAddrByName(text) + state.Push(lua.LString(addr)) + return 1 + }) +} diff --git a/vm/lua/glua/blockchain_test.go b/vm/lua/glua/blockchain_test.go index bedaaeb..06fa612 100644 --- a/vm/lua/glua/blockchain_test.go +++ b/vm/lua/glua/blockchain_test.go @@ -1,10 +1,11 @@ package glua import ( + "testing" + fcom "github.com/meshplus/hyperbench-common/common" "github.com/stretchr/testify/assert" lua "github.com/yuin/gopher-lua" - "testing" ) func Test_blockchain(t *testing.T) { @@ -45,6 +46,8 @@ func Test_blockchain(t *testing.T) { scripts := []string{` function run() ret = case.blockchain:Invoke({ + caller = "abc", + contract = "xxx", func="123", args={"123", "123"} },{aa="aa"},{bb="bb"}) @@ -54,6 +57,8 @@ func Test_blockchain(t *testing.T) { ` function run() ret = case.blockchain.Invoke({ + caller = "abc", + contract = "xxx", func="123", args={"123", "123"} },{aa="aa"},{bb="bb"}) @@ -67,7 +72,7 @@ func Test_blockchain(t *testing.T) { err = TableLua2GoStruct(ret.(*lua.LTable), result) assert.Nil(t, err) assert.Equal(t, result, &fcom.Result{Label: "label", UID: "UUID", BuildTime: 0, SendTime: 0, ConfirmTime: 0, WriteTime: 0, Status: "success", Ret: []interface{}{"demo", "demo"}}) - assert.Equal(t, client.tempData[Invoke], fcom.Invoke{"123", []interface{}{"123", "123"}}) + assert.Equal(t, client.tempData[Invoke], fcom.Invoke{"abc", "xxx", "123", []interface{}{"123", "123"}}) assert.Equal(t, client.tempData[Option], []fcom.Option{fcom.Option{"aa": "aa"}, fcom.Option{"bb": "bb"}}) } }) diff --git a/vm/lua/glua/glua_convert.go b/vm/lua/glua/glua_convert.go index 2be6bc4..fc37e61 100644 --- a/vm/lua/glua/glua_convert.go +++ b/vm/lua/glua/glua_convert.go @@ -2,14 +2,16 @@ package glua import ( "encoding/json" + "fmt" + "reflect" + fcom "github.com/meshplus/hyperbench-common/common" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" - "github.com/yuin/gopher-lua" - "reflect" + lua "github.com/yuin/gopher-lua" ) -//Go2Lua convert go interface val to lua.LValue value and reutrn +// Go2Lua convert go interface val to lua.LValue value and reutrn func Go2Lua(L *lua.LState, val interface{}) lua.LValue { var ( jsonBytes []byte @@ -29,14 +31,17 @@ func Go2Lua(L *lua.LState, val interface{}) lua.LValue { // TableLua2GoStruct maps the lua table to the given struct pointer. func TableLua2GoStruct(tbl *lua.LTable, st interface{}) error { value, err := Lua2Go(tbl) + if err != nil { + return err + } mp, ok := value.(map[string]interface{}) if !ok { return errors.New("arguments #1 must be a table, but got an array") } + config := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: st, - TagName: "lua", ErrorUnused: false, } decoder, err := mapstructure.NewDecoder(config) @@ -122,10 +127,12 @@ func go2Lua(L *lua.LState, value interface{}) lua.LValue { tbl.RawSetH(lua.LString(key), go2Lua(L, item)) } return tbl + case []byte: + return lua.LString(converted) case nil: return lua.LNil } - panic("unreachable") + panic(fmt.Sprintf("lua value: %T", value)) } // go2luaStruct convert struct for Implementation lua.table to lua.Table @@ -138,11 +145,11 @@ func go2luaStruct(L *lua.LState, value interface{}) (lua.LValue, bool) { } } -// function run() -// local i = 0 -// print("----coro-----") -// return i -// end +// function run() +// local i = 0 +// print("----coro-----") +// return i +// end func runLuaRunFunc(state *lua.LState, script string) (lua.LValue, error) { //exec lua run func err := state.DoString(script) diff --git a/vm/lua/glua/glua_convert_test.go b/vm/lua/glua/glua_convert_test.go index fc69900..eb3b044 100644 --- a/vm/lua/glua/glua_convert_test.go +++ b/vm/lua/glua/glua_convert_test.go @@ -1,17 +1,35 @@ package glua import ( + "testing" + + "github.com/meshplus/hyperbench-common/common" "github.com/stretchr/testify/assert" lua "github.com/yuin/gopher-lua" - "testing" ) func Test_Go2Lua(t *testing.T) { t.Run("demo", func(t *testing.T) { - str :="demo" + str := "demo" L := lua.NewState() - strLua := Go2Lua(L,str) - assert.Equal(t, strLua,lua.LString("demo")) + strLua := Go2Lua(L, str) + assert.Equal(t, strLua, lua.LString("demo")) }) } + +func Test_TableLua2GoStruct(t *testing.T) { + l := lua.NewState() + err := l.DoString( + `return { + caller = fromAddr, + contract = "ERC20", + func = "transfer", + args = {"toAddr", 111}, + }`) + assert.Nil(t, err) + luaValue := l.CheckTable(1) + result := &common.Invoke{} + err = TableLua2GoStruct(luaValue, result) + assert.Nil(t, err) +} diff --git a/vm/lua/glua/index.go b/vm/lua/glua/index.go index 7ed82e0..643af9d 100644 --- a/vm/lua/glua/index.go +++ b/vm/lua/glua/index.go @@ -11,5 +11,6 @@ func newIdexIndex(L *lua.LState, idx *idex.Index) lua.LValue { idxTable.RawSetString("VM", lua.LNumber(idx.VM)) idxTable.RawSetString("Engine", lua.LNumber(idx.Engine)) idxTable.RawSetString("Tx", lua.LNumber(idx.Tx)) + idxTable.RawSetString("Accounts", lua.LNumber(idx.Accounts)) return idxTable } diff --git a/vm/lua/glua/index_test.go b/vm/lua/glua/index_test.go index 68763ee..a99d0a6 100644 --- a/vm/lua/glua/index_test.go +++ b/vm/lua/glua/index_test.go @@ -1,10 +1,11 @@ package glua import ( + "testing" + "github.com/meshplus/hyperbench/plugins/index" "github.com/stretchr/testify/assert" lua "github.com/yuin/gopher-lua" - "testing" ) func Test_index(t *testing.T) { @@ -12,7 +13,7 @@ func Test_index(t *testing.T) { defer L.Close() mt := L.NewTypeMetatable("case") L.SetGlobal("case", mt) - passIdx := &index.Index{1, 1, 1, 1} + passIdx := &index.Index{1, 1, 1, 1, 1} cLua := newIdexIndex(L, passIdx) L.SetField(mt, "index", cLua) diff --git a/vm/lua/glua/mock_blockchain.go b/vm/lua/glua/mock_blockchain.go index 5486d3a..4347eca 100644 --- a/vm/lua/glua/mock_blockchain.go +++ b/vm/lua/glua/mock_blockchain.go @@ -101,3 +101,19 @@ func (chain *FakeChain) Statistic(statistic fcom.Statistic) (*fcom.RemoteStatist func (chain *FakeChain) LogStatus() (int64, error) { return 0, nil } + +func (chain *FakeChain) GetRandomAccountByGroup() string { + return "" +} + +func (chain *FakeChain) GetRandomAccount(account string) string { + return "" +} + +func (chain *FakeChain) GetAccount(index uint64) string { + return "" +} + +func (chain *FakeChain) GetContractAddrByName(name string) string { + return "" +} diff --git a/vm/lua/lua.go b/vm/lua/lua.go index 4886d7f..17de3dc 100644 --- a/vm/lua/lua.go +++ b/vm/lua/lua.go @@ -2,6 +2,7 @@ package lua import ( "errors" + "github.com/meshplus/hyperbench/vm/lua/glua" base2 "github.com/meshplus/hyperbench-common/base" @@ -37,8 +38,10 @@ func NewVM(base *base.VMBase) (vm *VM, err error) { vm = &VM{ VMBase: base, index: &idex.Index{ - Worker: base.Ctx.WorkerIdx, - VM: base.Ctx.VMIdx, + Worker: base.Ctx.WorkerIdx, + VM: base.Ctx.VMIdx, + Engine: base.Ctx.Engine, + Accounts: base.Ctx.Accounts, }, } @@ -210,7 +213,6 @@ func (v *VM) BeforeRun() error { // Run create and send tx to client. func (v *VM) Run(ctx fcom.TxContext) (*fcom.Result, error) { - v.index.Engine = ctx.EngineIdx v.index.Tx = ctx.TxIdx err := v.vm.CallByParam(lua.P{ @@ -262,6 +264,7 @@ func (v *VM) setPlugins(table *lua.LTable) (err error) { args, _ := viper.Get(fcom.ClientContractArgsPath).([]interface{}) options["vmIdx"] = v.index.VM options["wkIdx"] = v.index.Worker + v.client, err = blockchain.NewBlockchain(base2.ClientConfig{ ClientType: clientType, ConfigPath: clientConfigPath,