diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts index 4d050ac7..f60bf3f3 100644 --- a/packages/constants/src/index.ts +++ b/packages/constants/src/index.ts @@ -1,6 +1,7 @@ export * from "./addresses"; export * from "./chains"; export * from "./gas"; +export * from "./oracles"; export * from "./prices"; export * from "./protocol"; export * from "./tokens"; diff --git a/packages/constants/src/oracles.ts b/packages/constants/src/oracles.ts new file mode 100644 index 00000000..e0bdf63d --- /dev/null +++ b/packages/constants/src/oracles.ts @@ -0,0 +1,9 @@ +import { BigNumber } from "@ethersproject/bignumber"; + +export const DEFAULT_CARDINALITY: number = 144; +export const DEFAULT_TWAP_INTERVAL: number = 1800; +export const Q192: BigNumber = BigNumber.from("6277101735386680763835789423207666416102355444464034512896"); +export const TICKS = { + lowerBound: -798544800, + upperBound: 798544800, +}; diff --git a/packages/errors/src/index.ts b/packages/errors/src/index.ts index 5c4c9c29..a00a57eb 100644 --- a/packages/errors/src/index.ts +++ b/packages/errors/src/index.ts @@ -7,6 +7,9 @@ export { OwnableErrors } from "./external"; // flashSwap.ts export { FlashUniswapV2Errors, FlashUniswapV3Errors } from "./flashSwap"; +// oracles.ts +export { UniswapV3PriceFeedErrors } from "./oracles"; + // protocol.ts export { BalanceSheetErrors, diff --git a/packages/errors/src/oracles.ts b/packages/errors/src/oracles.ts new file mode 100644 index 00000000..83c5daf6 --- /dev/null +++ b/packages/errors/src/oracles.ts @@ -0,0 +1,5 @@ +export enum UniswapV3PriceFeedErrors { + QUOTE_ASSET_NOT_IN_POOL = "IUniswapV3PriceFeed__QuoteAssetNotInPool", + TWAP_CRITERIA_NOT_SATISFIED = "IUniswapV3PriceFeed__TwapCriteriaNotSatisfied", + MAX_PRICE_LESS_THAN_OR_EQUAL_TO_ZERO = "IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero", +} diff --git a/packages/flash-swap/contracts/uniswap-v3/NoDelegateCall.sol b/packages/flash-swap/contracts/uniswap-v3/NoDelegateCall.sol index 59d39f48..5892544d 100644 --- a/packages/flash-swap/contracts/uniswap-v3/NoDelegateCall.sol +++ b/packages/flash-swap/contracts/uniswap-v3/NoDelegateCall.sol @@ -2,8 +2,7 @@ // solhint-disable pragma solidity =0.7.6; -/// @title Prevents delegatecall to a contract -/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract +/// @dev https://raw.githubusercontent.com/Uniswap/v3-core/v1.0.0/contracts/NoDelegateCall.sol abstract contract NoDelegateCall { /// @dev The original address of this contract address private immutable original; diff --git a/packages/flash-swap/contracts/uniswap-v3/UniswapV3Pool.sol b/packages/flash-swap/contracts/uniswap-v3/UniswapV3Pool.sol index e9553d1a..addd33ed 100644 --- a/packages/flash-swap/contracts/uniswap-v3/UniswapV3Pool.sol +++ b/packages/flash-swap/contracts/uniswap-v3/UniswapV3Pool.sol @@ -28,6 +28,7 @@ import "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.so import "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol"; import "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol"; +/// @dev https://raw.githubusercontent.com/Uniswap/v3-core/v1.0.0/contracts/UniswapV3Pool.sol contract UniswapV3Pool is IUniswapV3Pool, NoDelegateCall { using LowGasSafeMath for uint256; using LowGasSafeMath for int256; diff --git a/packages/flash-swap/src/types/factories/contracts/uniswap-v3/UniswapV3Pool__factory.ts b/packages/flash-swap/src/types/factories/contracts/uniswap-v3/UniswapV3Pool__factory.ts index 263ab8e6..ae902a1d 100644 --- a/packages/flash-swap/src/types/factories/contracts/uniswap-v3/UniswapV3Pool__factory.ts +++ b/packages/flash-swap/src/types/factories/contracts/uniswap-v3/UniswapV3Pool__factory.ts @@ -1000,7 +1000,7 @@ const _abi = [ ]; const _bytecode = - "0x6101206040523480156200001257600080fd5b503060601b60805260408051630890357360e41b81529051600091339163890357309160048082019260a092909190829003018186803b1580156200005657600080fd5b505afa1580156200006b573d6000803e3d6000fd5b505050506040513d60a08110156200008257600080fd5b508051602080830151604084015160608086015160809096015160e896871b6001600160e81b03191660c052600180546001600160a01b03199081166001600160a01b039586161790915560008054909116939094169290921790925592901b6001600160601b03191660a052600282810b900b90921b60e0529150620001149082906200012c811b62003de517901c565b60801b6001600160801b03191661010052506200019a565b60008082600281900b620d89e719816200014257fe5b05029050600083600281900b620d89e8816200015a57fe5b0502905060008460020b83830360020b816200017257fe5b0560010190508062ffffff166001600160801b038016816200019057fe5b0495945050505050565b60805160601c60a05160601c60c05160e81c60e05160e81c6101005160801c6176b66200021b60003980612c30528061684b5280616882525080610ed15280613a3052806168b652806168e8525080611039528061236052806123975280613a70525080612d4d528061303e5280613a0c525080613e8e52506176b66000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806370cf754a116100ee578063c45a015511610097578063ddca3f4311610071578063ddca3f43146108bd578063f3058399146108dd578063f30dba93146108e5578063f637731d1461097d576101ae565b8063c45a01551461088e578063d0c93a7c14610896578063d21220a7146108b5576101ae565b8063883bdbfd116100c8578063883bdbfd146106da578063a34123a7146107e3578063a38807f214610826576101ae565b806370cf754a146106575780638206a4d11461065f57806385b6672914610687576101ae565b80633850c7bd1161015b578063490e6cbc11610135578063490e6cbc146104d55780634f1eb3d81461056e578063514ea4bf146105d55780635339c29614610637576101ae565b80633850c7bd1461039d5780633c8a7d8d1461040357806346141319146104bb576101ae565b80631ad8b03b1161018c5780631ad8b03b146102cd578063252c09d71461031657806332148f671461037a576101ae565b80630dfe1681146101b3578063128acb08146101e45780631a686502146102a0575b600080fd5b6101bb6109b0565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610287600480360360a08110156101fa57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135151592604082013592606083013516919081019060a08101608082013564010000000081111561024857600080fd5b82018360208201111561025a57600080fd5b8035906020019184600183028401116401000000008311171561027c57600080fd5b5090925090506109cc565b6040805192835260208301919091528051918290030190f35b6102a8611a6f565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102d5611a87565b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6103336004803603602081101561032c57600080fd5b5035611ab7565b6040805163ffffffff909516855260069390930b602085015273ffffffffffffffffffffffffffffffffffffffff9091168383015215156060830152519081900360800190f35b61039b6004803603602081101561039057600080fd5b503561ffff16611b2e565b005b6103a5611d12565b6040805173ffffffffffffffffffffffffffffffffffffffff909816885260029690960b602088015261ffff9485168787015292841660608701529216608085015260ff90911660a0840152151560c0830152519081900360e00190f35b610287600480360360a081101561041957600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516916020810135600290810b92604083013590910b916fffffffffffffffffffffffffffffffff6060820135169181019060a08101608082013564010000000081111561047c57600080fd5b82018360208201111561048e57600080fd5b803590602001918460018302840111640100000000831117156104b057600080fd5b509092509050611df7565b6104c361220e565b60408051918252519081900360200190f35b61039b600480360360808110156104eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516916020810135916040820135919081019060808101606082013564010000000081111561052f57600080fd5b82018360208201111561054157600080fd5b8035906020019184600183028401116401000000008311171561056357600080fd5b509092509050612214565b6102d5600480360360a081101561058457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020810135600290810b91604081013590910b906fffffffffffffffffffffffffffffffff6060820135811691608001351661287a565b6105f2600480360360208110156105eb57600080fd5b5035612bc9565b604080516fffffffffffffffffffffffffffffffff96871681526020810195909552848101939093529084166060840152909216608082015290519081900360a00190f35b6104c36004803603602081101561064d57600080fd5b503560010b612c1c565b6102a8612c2e565b61039b6004803603604081101561067557600080fd5b5060ff81358116916020013516612c52565b6102d56004803603606081101561069d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906fffffffffffffffffffffffffffffffff60208201358116916040013516612f3e565b61074a600480360360208110156106f057600080fd5b81019060208101813564010000000081111561070b57600080fd5b82018360208201111561071d57600080fd5b8035906020019184602083028401116401000000008311171561073f57600080fd5b5090925090506133cc565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561078e578181015183820152602001610776565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156107cd5781810151838201526020016107b5565b5050505090500194505050505060405180910390f35b610287600480360360608110156107f957600080fd5b508035600290810b91602081013590910b90604001356fffffffffffffffffffffffffffffffff1661349f565b6108506004803603604081101561083c57600080fd5b508035600290810b9160200135900b6136f7565b6040805160069490940b845273ffffffffffffffffffffffffffffffffffffffff909216602084015263ffffffff1682820152519081900360600190f35b6101bb613a0a565b61089e613a2e565b6040805160029290920b8252519081900360200190f35b6101bb613a52565b6108c5613a6e565b6040805162ffffff9092168252519081900360200190f35b6104c3613a92565b610905600480360360208110156108fb57600080fd5b503560020b613a98565b604080516fffffffffffffffffffffffffffffffff9099168952600f9790970b602089015287870195909552606087019390935260069190910b608086015273ffffffffffffffffffffffffffffffffffffffff1660a085015263ffffffff1660c0840152151560e083015251908190036101000190f35b61039b6004803603602081101561099357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613b5d565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6000806109d7613e76565b85610a4357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4153000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6040805160e0810182526002805473ffffffffffffffffffffffffffffffffffffffff81168352740100000000000000000000000000000000000000008104820b820b90910b602083015261ffff7701000000000000000000000000000000000000000000000082048116938301939093527901000000000000000000000000000000000000000000000000008104831660608301527b010000000000000000000000000000000000000000000000000000008104909216608082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660a08301527e01000000000000000000000000000000000000000000000000000000000000909204909116151560c08201819052610bc457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b87610c3657806000015173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16118015610c31575073fffd8963efd1fc6a506488495d951d5263988d2673ffffffffffffffffffffffffffffffffffffffff8716105b610c8f565b806000015173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16108015610c8f57506401000276a373ffffffffffffffffffffffffffffffffffffffff8716115b610cfa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53504c0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040805160c08101909152600090808a610d475760048460a0015160ff16901c610d5a565b60108460a0015160ff1681610d5857fe5b065b60ff1681526006546fffffffffffffffffffffffffffffffff166020820152604001610d84613eba565b63ffffffff168152602001600060060b8152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000151581525090506000808913905060006040518060e001604052808b815260200160008152602001856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015160020b81526020018c610e1a57600454610e1e565b6003545b815260200160006fffffffffffffffffffffffffffffffff16815260200184602001516fffffffffffffffffffffffffffffffff1681525090505b805115801590610e9957508873ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1614155b1561136857610ea661761d565b604082015173ffffffffffffffffffffffffffffffffffffffff1681526060820151610ef6906008907f00000000000000000000000000000000000000000000000000000000000000008f613ebe565b15156040830152600290810b810b602083018190527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618910b1215610f5f577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276186020820152610f7e565b6020810151620d89e860029190910b1315610f7e57620d89e860208201525b610f8b816020015161403c565b73ffffffffffffffffffffffffffffffffffffffff166060820152604082015161105d908d610fec578b73ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff1611611020565b8b73ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16105b61102e578260600151611030565b8b5b60c085015185517f00000000000000000000000000000000000000000000000000000000000000006143cf565b60c085015260a0840152608083015273ffffffffffffffffffffffffffffffffffffffff16604083015282156110cc576110a08160c001518260800151016145f5565b825103825260a08101516110c2906110b7906145f5565b602084015190614627565b6020830152611107565b6110d98160a001516145f5565b825101825260c08101516080820151611101916110f691016145f5565b602084015190614643565b60208301525b835160ff1615611156576000846000015160ff168260c001518161112757fe5b60c0840180519290910491829003905260a0840180519091016fffffffffffffffffffffffffffffffff169052505b60c08201516fffffffffffffffffffffffffffffffff16156111b4576111a88160c001517001000000000000000000000000000000008460c001516fffffffffffffffffffffffffffffffff16614659565b60808301805190910190525b806060015173ffffffffffffffffffffffffffffffffffffffff16826040015173ffffffffffffffffffffffffffffffffffffffff16141561130d578060400151156112e4578360a0015161126557611236846040015160008760200151886040015188602001518a60600151600a614727909695949392919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff166080860152600690810b900b6060850152600160a08501525b60006112b182602001518e61127c57600354611282565b84608001515b8f611291578560800151611295565b6004545b608089015160608a015160408b015160079594939291906148f8565b90508c156112bd576000035b6112cb8360c0015182614a2d565b6fffffffffffffffffffffffffffffffff1660c0840152505b8b6112f35780602001516112fc565b60018160200151035b600290810b900b6060830152611362565b806000015173ffffffffffffffffffffffffffffffffffffffff16826040015173ffffffffffffffffffffffffffffffffffffffff1614611362576113558260400151614b71565b600290810b900b60608301525b50610e59565b836020015160020b816060015160020b146114e0576000806113b686604001518660400151886020015188602001518a606001518b60800151600a614f3d909695949392919063ffffffff16565b60408501516060860151600280547fffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff1679010000000000000000000000000000000000000000000000000061ffff95861602177fffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000009590941694909402929092177fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000062ffffff93850b9390931692909202919091177fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161790555061152a9050565b6040810151600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790555b8060c001516fffffffffffffffffffffffffffffffff1683602001516fffffffffffffffffffffffffffffffff16146115a35760c0810151600680547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9092169190911790555b8a1561161d57608081015160035560a08101516fffffffffffffffffffffffffffffffff16156116185760a0810151600580547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff918216909301169190911790555b611682565b608081015160045560a08101516fffffffffffffffffffffffffffffffff16156116825760a0810151600580546fffffffffffffffffffffffffffffffff80821670010000000000000000000000000000000092839004821690940116029190911790555b8115158b15151461169b57602081015181518b036116a8565b80600001518a0381602001515b90965094508a1561181c5760008512156116e4576001546116e49073ffffffffffffffffffffffffffffffffffffffff168d6000889003615183565b60006116ee61535f565b90503373ffffffffffffffffffffffffffffffffffffffff1663fa461e3388888c8c6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561177f57600080fd5b505af1158015611793573d6000803e3d6000fd5b5050505061179f61535f565b6117a982896154d1565b111561181657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4949410000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b50611987565b60008612156118535761185360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d88600003615183565b600061185d6154e1565b90503373ffffffffffffffffffffffffffffffffffffffff1663fa461e3388888c8c6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156118ee57600080fd5b505af1158015611902573d6000803e3d6000fd5b5050505061190e6154e1565b61191882886154d1565b111561198557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4949410000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b505b60408082015160c083015160608085015184518b8152602081018b905273ffffffffffffffffffffffffffffffffffffffff948516818701526fffffffffffffffffffffffffffffffff9093169183019190915260020b60808201529151908e169133917fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679181900360a00190a35050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550919890975095505050505050565b6006546fffffffffffffffffffffffffffffffff1681565b6005546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041682565b600a8161ffff8110611ac857600080fd5b015463ffffffff81169150640100000000810460060b906b010000000000000000000000810473ffffffffffffffffffffffffffffffffffffffff16907f0100000000000000000000000000000000000000000000000000000000000000900460ff1684565b6002547e01000000000000000000000000000000000000000000000000000000000000900460ff16611bc157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055611bf1613e76565b6002547b01000000000000000000000000000000000000000000000000000000900461ffff166000611c25600a83856155b4565b6002805461ffff8084167b0100000000000000000000000000000000000000000000000000000081027fffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff90931692909217909255919250831614611cc4576040805161ffff80851682528316602082015281517fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a929181900390910190a15b5050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550565b6002805473ffffffffffffffffffffffffffffffffffffffff811691740100000000000000000000000000000000000000008204900b9061ffff77010000000000000000000000000000000000000000000000820481169179010000000000000000000000000000000000000000000000000081048216917b010000000000000000000000000000000000000000000000000000008204169060ff7d01000000000000000000000000000000000000000000000000000000000082048116917e0100000000000000000000000000000000000000000000000000000000000090041687565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff16611e8f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556fffffffffffffffffffffffffffffffff8516611ed357600080fd5b600080611f3760405180608001604052808c73ffffffffffffffffffffffffffffffffffffffff1681526020018b60020b81526020018a60020b8152602001611f2d8a6fffffffffffffffffffffffffffffffff166156a8565b600f0b90526156b9565b92509250508193508092506000806000861115611f5957611f5661535f565b91505b8415611f6a57611f676154e1565b90505b3373ffffffffffffffffffffffffffffffffffffffff1663d348799787878b8b6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611ff957600080fd5b505af115801561200d573d6000803e3d6000fd5b5050505060008611156120995761202261535f565b61202c83886154d1565b111561209957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4d30000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b841561211e576120a76154e1565b6120b182876154d1565b111561211e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4d31000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8960020b8b60020b8d73ffffffffffffffffffffffffffffffffffffffff167f7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde338d8b8b604051808573ffffffffffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a45050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550919890975095505050505050565b60045481565b6002547e01000000000000000000000000000000000000000000000000000000000000900460ff166122a757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556122d7613e76565b6006546fffffffffffffffffffffffffffffffff168061235857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f4c00000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600061238d867f000000000000000000000000000000000000000000000000000000000000000062ffffff16620f4240615a15565b905060006123c4867f000000000000000000000000000000000000000000000000000000000000000062ffffff16620f4240615a15565b905060006123d061535f565b905060006123dc6154e1565b90508815612408576000546124089073ffffffffffffffffffffffffffffffffffffffff168b8b615183565b8715612432576001546124329073ffffffffffffffffffffffffffffffffffffffff168b8a615183565b3373ffffffffffffffffffffffffffffffffffffffff1663e9cbafb085858a8a6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156124c157600080fd5b505af11580156124d5573d6000803e3d6000fd5b5050505060006124e361535f565b905060006124ef6154e1565b9050816124fc85886154d1565b111561256957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4630000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8061257484876154d1565b11156125e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4631000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b83820383820381156126ca576002547d0100000000000000000000000000000000000000000000000000000000009004600f166000811561262e578160ff16848161262857fe5b04612631565b60005b90506fffffffffffffffffffffffffffffffff81161561268e57600580546fffffffffffffffffffffffffffffffff8082168401167fffffffffffffffffffffffffffffffff000000000000000000000000000000009091161790555b6126be8185037001000000000000000000000000000000008d6fffffffffffffffffffffffffffffffff16614659565b60038054909101905550505b80156127a4576002547d010000000000000000000000000000000000000000000000000000000000900460041c600f1660008115612714578160ff16838161270e57fe5b04612717565b60005b90506fffffffffffffffffffffffffffffffff81161561276857600580546fffffffffffffffffffffffffffffffff7001000000000000000000000000000000008083048216850182160291161790555b6127988184037001000000000000000000000000000000008d6fffffffffffffffffffffffffffffffff16614659565b60048054909101905550505b8d73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca6338f8f86866040518085815260200184815260200183815260200182815260200194505050505060405180910390a35050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055505050505050505050505050565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff1661291257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905560006129496009338989615a6d565b60038101549091506fffffffffffffffffffffffffffffffff90811690861611612973578461298b565b60038101546fffffffffffffffffffffffffffffffff165b60038201549093506fffffffffffffffffffffffffffffffff7001000000000000000000000000000000009091048116908516116129c957836129f5565b600381015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b91506fffffffffffffffffffffffffffffffff831615612a7e576003810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff918216869003821617909155600054612a7e9173ffffffffffffffffffffffffffffffffffffffff909116908a908616615183565b6fffffffffffffffffffffffffffffffff821615612afd576003810180546fffffffffffffffffffffffffffffffff700100000000000000000000000000000000808304821686900382160291811691909117909155600154612afd9173ffffffffffffffffffffffffffffffffffffffff909116908a908516615183565b6040805173ffffffffffffffffffffffffffffffffffffffff8a1681526fffffffffffffffffffffffffffffffff80861660208301528416818301529051600288810b92908a900b9133917f70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0919081900360600190a450600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905590969095509350505050565b60096020526000908152604090208054600182015460028301546003909301546fffffffffffffffffffffffffffffffff9283169391928181169170010000000000000000000000000000000090041685565b60086020526000908152604090205481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6002547e01000000000000000000000000000000000000000000000000000000000000900460ff16612ce557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691638da5cb5b916004808301926020929190829003018186803b158015612d9357600080fd5b505afa158015612da7573d6000803e3d6000fd5b505050506040513d6020811015612dbd57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612de057600080fd5b60ff82161580612e03575060048260ff1610158015612e035750600a8260ff1611155b8015612e2d575060ff81161580612e2d575060048160ff1610158015612e2d5750600a8160ff1611155b612e3657600080fd5b60028054610ff0600484901b16840160ff9081167d0100000000000000000000000000000000000000000000000000000000009081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841617909355919004167f973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b1336010826040805160ff9390920683168252600f600486901c16602083015286831682820152918516606082015290519081900360800190a15050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff16612fd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691638da5cb5b916004808301926020929190829003018186803b15801561308457600080fd5b505afa158015613098573d6000803e3d6000fd5b505050506040513d60208110156130ae57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1633146130d157600080fd5b6005546fffffffffffffffffffffffffffffffff908116908516116130f6578361310c565b6005546fffffffffffffffffffffffffffffffff165b6005549092506fffffffffffffffffffffffffffffffff7001000000000000000000000000000000009091048116908416116131485782613172565b60055470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b90506fffffffffffffffffffffffffffffffff82161561323e576005546fffffffffffffffffffffffffffffffff838116911614156131d1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b600580547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821685900382161790915560005461323e9173ffffffffffffffffffffffffffffffffffffffff9091169087908516615183565b6fffffffffffffffffffffffffffffffff811615613311576005546fffffffffffffffffffffffffffffffff8281167001000000000000000000000000000000009092041614156132ac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff015b600580546fffffffffffffffffffffffffffffffff7001000000000000000000000000000000008083048216859003821602918116919091179091556001546133119173ffffffffffffffffffffffffffffffffffffffff9091169087908416615183565b604080516fffffffffffffffffffffffffffffffff808516825283166020820152815173ffffffffffffffffffffffffffffffffffffffff88169233927f596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151929081900390910190a3600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790559094909350915050565b6060806133d7613e76565b6134946133e2613eba565b8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060028054600654600a9695945074010000000000000000000000000000000000000000820490920b925061ffff7701000000000000000000000000000000000000000000000082048116926fffffffffffffffffffffffffffffffff1691790100000000000000000000000000000000000000000000000000900416615ae4565b915091509250929050565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff1661353757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681556040805160808101825233815287830b60208201529186900b90820152600090819081906135b390606081016135a66fffffffffffffffffffffffffffffffff8a166156a8565b600003600f0b90526156b9565b92509250925081600003945080600003935060008511806135d45750600084115b15613641576003830180546fffffffffffffffffffffffffffffffff808216808901821670010000000000000000000000000000000093849004831689019092169092029091177fffffffffffffffffffffffffffffffff00000000000000000000000000000000161790555b604080516fffffffffffffffffffffffffffffffff88168152602081018790528082018690529051600289810b92908b900b9133917f0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c919081900360600190a45050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055509094909350915050565b6000806000613704613e76565b61370e8585615c8e565b600285810b810b60009081526007602052604080822087840b90930b825281206003830154600681900b93670100000000000000820473ffffffffffffffffffffffffffffffffffffffff169284927b01000000000000000000000000000000000000000000000000000000810463ffffffff1692849290917f0100000000000000000000000000000000000000000000000000000000000000900460ff16806137b757600080fd5b6003820154600681900b9850670100000000000000810473ffffffffffffffffffffffffffffffffffffffff1696507b01000000000000000000000000000000000000000000000000000000810463ffffffff1694507f0100000000000000000000000000000000000000000000000000000000000000900460ff168061383d57600080fd5b50506040805160e0810182526002805473ffffffffffffffffffffffffffffffffffffffff81168352740100000000000000000000000000000000000000008104820b820b820b6020840181905261ffff7701000000000000000000000000000000000000000000000083048116958501959095527901000000000000000000000000000000000000000000000000008204851660608501527b010000000000000000000000000000000000000000000000000000008204909416608084015260ff7d0100000000000000000000000000000000000000000000000000000000008204811660a08501527e0100000000000000000000000000000000000000000000000000000000000090910416151560c08301529093508e810b91900b1215905061397757509390940396509003935090039050613a03565b8a60020b816020015160020b12156139f4576000613993613eba565b60208301516040840151600654606086015193945060009384936139d293600a938893879392916fffffffffffffffffffffffffffffffff1690614727565b9a9003989098039b505094909603929092039650909103039250613a03915050565b50949093039650039350900390505b9250925092565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b60076020526000908152604090208054600182015460028301546003909301546fffffffffffffffffffffffffffffffff831693700100000000000000000000000000000000909304600f0b9290600681900b90670100000000000000810473ffffffffffffffffffffffffffffffffffffffff16907b01000000000000000000000000000000000000000000000000000000810463ffffffff16907f0100000000000000000000000000000000000000000000000000000000000000900460ff1688565b60025473ffffffffffffffffffffffffffffffffffffffff1615613be257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4149000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000613bed82614b71565b9050600080613c05613bfd613eba565b600a90615e0f565b6040805160e08101825273ffffffffffffffffffffffffffffffffffffffff8816808252600288810b6020808501829052600085870181905261ffff898116606088018190529089166080880181905260a0880192909252600160c09097019690965283547e010000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffff000000000000000000000000000000000000000090911686177fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000062ffffff86880b1602177fffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffff16790100000000000000000000000000000000000000000000000000909702969096177fffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff167b01000000000000000000000000000000000000000000000000000000909102177fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169490941790915583519182529181019190915281519395509193507f98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c9592918290030190a150505050565b60008082600281900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761881613e1657fe5b05029050600083600281900b620d89e881613e2d57fe5b0502905060008460020b83830360020b81613e4457fe5b0560010190508062ffffff166fffffffffffffffffffffffffffffffff801681613e6a57fe5b0493505050505b919050565b3073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614613eb857600080fd5b565b4290565b60008060008460020b8660020b81613ed257fe5b05905060008660020b128015613ef957508460020b8660020b81613ef257fe5b0760020b15155b15613f21577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff015b8315613fb457600080613f3383615e92565b600182810b810b600090815260208d9052604090205460ff83169190911b80017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190811680151597509294509092509085613f9657888360ff16860302613fa9565b88613fa082615ea4565b840360ff168603025b965050505050614032565b600080613fc383600101615e92565b91509150600060018260ff166001901b031990506000818b60008660010b60010b815260200190815260200160002054169050806000141595508561401557888360ff0360ff1686600101010261402b565b888361402083615f51565b0360ff168660010101025b9650505050505b5094509492505050565b60008060008360020b12614053578260020b61405b565b8260020b6000035b9050620d89e88111156140cf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f5400000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000600182166140f057700100000000000000000000000000000000614102565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615614136576ffff97272373d413259a46990580e213a0260801c5b6004821615614155576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614174576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615614193576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156141b2576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156141d1576fff2ea16466c96a3843ec78b326b528610260801c5b60808216156141f0576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615614210576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615614230576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615614250576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615614270576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615614290576fd097f3bdfd2022b8845ad8f792aa58250260801c5b6120008216156142b0576fa9f746462d870fdf8a65dc1f90e061e50260801c5b6140008216156142d0576f70d869a156d2a1b890bb3df62baf32f70260801c5b6180008216156142f0576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615614311576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615614331576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615614350576d2216e584f5fa1ea926041bedfe980260801c5b6208000082161561436d576b048a170391f7dc42444e8fa20260801c5b60008460020b13156143a657807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff816143a257fe5b0490505b6401000000008106156143ba5760016143bd565b60005b60ff16602082901c0192505050919050565b600080808073ffffffffffffffffffffffffffffffffffffffff808916908a1610158187128015906144615760006144158989620f42400362ffffff16620f4240614659565b90508261442e576144298c8c8c6001616134565b61443b565b61443b8b8d8c6001616207565b955085811061444c578a965061445b565b6144588c8b838661631f565b96505b506144ab565b81614478576144738b8b8b6000616207565b614485565b6144858a8c8b6000616134565b9350838860000310614499578995506144ab565b6144a88b8a8a60000385616381565b95505b73ffffffffffffffffffffffffffffffffffffffff8a811690871614821561451b578080156144d75750815b6144ed576144e8878d8c6001616207565b6144ef565b855b95508080156144fc575081155b6145125761450d878d8c6000616134565b614514565b845b9450614565565b8080156145255750815b61453b576145368c888c6001616134565b61453d565b855b955080801561454a575081155b6145605761455b8c888c6000616207565b614562565b845b94505b8115801561457557508860000385115b15614581578860000394505b8180156145ba57508a73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b156145c95785890393506145e6565b6145e3868962ffffff168a620f42400362ffffff16615a15565b93505b50505095509550955095915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821061462357600080fd5b5090565b8082038281131560008312151461463d57600080fd5b92915050565b8181018281121560008312151461463d57600080fd5b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff858709868602925082811090839003039050806146ad57600084116146a257600080fd5b508290049050614720565b8084116146b957600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150505b9392505050565b60008063ffffffff87166147ff576000898661ffff1661ffff811061474857fe5b60408051608081018252919092015463ffffffff8082168084526401000000008304600690810b810b900b60208501526b010000000000000000000000830473ffffffffffffffffffffffffffffffffffffffff16948401949094527f010000000000000000000000000000000000000000000000000000000000000090910460ff16151560608301529092508a16146147eb576147e8818a89886163e3565b90505b8060200151816040015192509250506148ec565b8688036000806148148c8c858c8c8c8c6164b2565b91509150816000015163ffffffff168363ffffffff1614156148465781602001518260400151945094505050506148ec565b805163ffffffff8481169116141561486e5780602001518160400151945094505050506148ec565b8151815160208085015190840151918390039286039163ffffffff80841692908516910360060b8161489c57fe5b05028460200151018263ffffffff168263ffffffff16866040015186604001510373ffffffffffffffffffffffffffffffffffffffff1602816148db57fe5b048560400151019650965050505050505b97509795505050505050565b600295860b860b60009081526020979097526040909620600181018054909503909455938301805490920390915560038201805463ffffffff7b0100000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff6701000000000000008085048216909603169094027fffffffffff0000000000000000000000000000000000000000ffffffffffffff90921691909117600681810b90960390950b66ffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000909516949094178281048516909503909316027fff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff909316929092179055547001000000000000000000000000000000009004600f0b90565b60008082600f0b1215614ad957826fffffffffffffffffffffffffffffffff168260000384039150816fffffffffffffffffffffffffffffffff1610614ad457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4c53000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61463d565b826fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff16101561463d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4c41000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60006401000276a373ffffffffffffffffffffffffffffffffffffffff831610801590614bc7575073fffd8963efd1fc6a506488495d951d5263988d2673ffffffffffffffffffffffffffffffffffffffff8316105b614c3257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f5200000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b77ffffffffffffffffffffffffffffffffffffffff00000000602083901b166fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c97908811961790941790921717909117171760808110614cdc57607f810383901c9150614ce6565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808f0160401b60c09190911c678000000000000000161760c19b909b1c674000000000000000169a909a1760c29990991c672000000000000000169890981760c39790971c671000000000000000169690961760c49590951c670800000000000000169490941760c59390931c670400000000000000169290921760c69190911c670200000000000000161760c79190911c670100000000000000161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617693627a301d71055774c8581027ffffffffffffffffffffffffffffffffffd709b7e5480fba5a50fed5e62ffc5568101608090811d906fdb2df09e81959a81455e260799a0632f8301901d600281810b9083900b14614f2e578873ffffffffffffffffffffffffffffffffffffffff16614f058261403c565b73ffffffffffffffffffffffffffffffffffffffff161115614f275781614f29565b805b614f30565b815b9998505050505050505050565b6000806000898961ffff1661ffff8110614f5357fe5b60408051608081018252919092015463ffffffff8082168084526401000000008304600690810b810b900b60208501526b010000000000000000000000830473ffffffffffffffffffffffffffffffffffffffff16948401949094527f010000000000000000000000000000000000000000000000000000000000000090910460ff161515606083015290925089161415614ff457888592509250506148ec565b8461ffff168461ffff1611801561501557506001850361ffff168961ffff16145b1561502257839150615026565b8491505b8161ffff168960010161ffff168161503a57fe5b069250615049818989896163e3565b8a8461ffff1661ffff811061505a57fe5b8251910180546020840151604085015160609095015115157f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff9096166b010000000000000000000000027fff0000000000000000000000000000000000000000ffffffffffffffffffffff60069390930b66ffffffffffffff16640100000000027fffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff63ffffffff9097167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009095169490941795909516929092171692909217929092161790555097509795505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061525857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161521b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146152ba576040519150601f19603f3d011682016040523d82523d6000602084013e6152bf565b606091505b50915091508180156152ed5750805115806152ed57508080602001905160208110156152ea57600080fd5b50515b61535857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5446000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b60008054604080513060248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a0823100000000000000000000000000000000000000000000000000000000178152915181518594859473ffffffffffffffffffffffffffffffffffffffff9091169392918291908083835b6020831061543157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016153f4565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615491576040519150601f19603f3d011682016040523d82523d6000602084013e615496565b606091505b50915091508180156154aa57506020815110155b6154b357600080fd5b8080602001905160208110156154c857600080fd5b50519250505090565b8082018281101561463d57600080fd5b600154604080513060248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a0823100000000000000000000000000000000000000000000000000000000178152915181516000948594859473ffffffffffffffffffffffffffffffffffffffff9092169391928291908083836020831061543157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016153f4565b6000808361ffff161161562857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f4900000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8261ffff168261ffff161161563e575081614720565b825b8261ffff168161ffff16101561569f576001858261ffff1661ffff811061566357fe5b0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff92909216919091179055600101615640565b50909392505050565b80600f81900b8114613e7157600080fd5b60008060006156c6613e76565b6156d884602001518560400151615c8e565b6040805160e0810182526002805473ffffffffffffffffffffffffffffffffffffffff81168352740100000000000000000000000000000000000000008104820b820b90910b602080840182905261ffff770100000000000000000000000000000000000000000000008404811685870152790100000000000000000000000000000000000000000000000000840481166060808701919091527b010000000000000000000000000000000000000000000000000000008504909116608086015260ff7d0100000000000000000000000000000000000000000000000000000000008504811660a08701527e01000000000000000000000000000000000000000000000000000000000000909404909316151560c0850152885190890151948901519289015193946158109491939092909190616776565b93508460600151600f0b600014615a0d57846020015160020b816020015160020b12156158655761585e615847866020015161403c565b615854876040015161403c565b8760600151616970565b9250615a0d565b846040015160020b816020015160020b12156159e35760065460408201516fffffffffffffffffffffffffffffffff909116906158c0906158a4613eba565b602085015160608601516080870151600a949392918791614f3d565b600280547fffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff1679010000000000000000000000000000000000000000000000000061ffff93841602177fffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff167701000000000000000000000000000000000000000000000093909216929092021790558151604087015161596e91906159649061403c565b8860600151616970565b935061598c615980876020015161403c565b835160608901516169b4565b925061599c818760600151614a2d565b600680547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691909117905550615a0d565b615a0a6159f3866020015161403c565b615a00876040015161403c565b87606001516169b4565b91505b509193909250565b6000615a22848484614659565b905060008280615a2e57fe5b8486091115614720577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110615a6357600080fd5b6001019392505050565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080860191909152600293840b60e890811b60348701529290930b90911b60378401528051808403601a018152603a90930181528251928201929092206000908152929052902090565b60608060008361ffff1611615b5a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f4900000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b865167ffffffffffffffff81118015615b7257600080fd5b50604051908082528060200260200182016040528015615b9c578160200160208202803683370190505b509150865167ffffffffffffffff81118015615bb757600080fd5b50604051908082528060200260200182016040528015615be1578160200160208202803683370190505b50905060005b8751811015615c8157615c128a8a8a8481518110615c0157fe5b60200260200101518a8a8a8a614727565b848381518110615c1e57fe5b60200260200101848481518110615c3157fe5b602002602001018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152508260060b60060b81525050508080600101915050615be7565b5097509795505050505050565b8060020b8260020b12615d0257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f544c550000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618600283900b1215615d9557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f544c4d0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b620d89e8600282900b1315615e0b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f54554d0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b5050565b6040805160808101825263ffffffff928316808252600060208301819052928201929092526001606090910181905283547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000169091179091167f010000000000000000000000000000000000000000000000000000000000000017909155908190565b60020b600881901d9161010090910790565b6000808211615eb257600080fd5b7001000000000000000000000000000000008210615ed257608091821c91015b680100000000000000008210615eea57604091821c91015b6401000000008210615efe57602091821c91015b620100008210615f1057601091821c91015b6101008210615f2157600891821c91015b60108210615f3157600491821c91015b60048210615f4157600291821c91015b60028210613e7157600101919050565b6000808211615f5f57600080fd5b5060ff6fffffffffffffffffffffffffffffffff821615615fa1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8001615fa9565b608082901c91505b67ffffffffffffffff821615615fe0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001615fe8565b604082901c91505b63ffffffff82161561601b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001616023565b602082901c91505b61ffff821615616054577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00161605c565b601082901c91505b60ff82161561608c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff801616094565b600882901c91505b600f8216156160c4577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc016160cc565b600482901c91505b60038216156160fc577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01616104565b600282901c91505b6001821615613e71577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01919050565b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561616e579293925b816161ba576161b5836fffffffffffffffffffffffffffffffff1686860373ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000614659565b6161fc565b6161fc836fffffffffffffffffffffffffffffffff1686860373ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000615a15565b90505b949350505050565b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115616241579293925b7bffffffffffffffffffffffffffffffff000000000000000000000000606084901b1673ffffffffffffffffffffffffffffffffffffffff868603811690871661628a57600080fd5b836162d4578673ffffffffffffffffffffffffffffffffffffffff166162c783838973ffffffffffffffffffffffffffffffffffffffff16614659565b816162ce57fe5b04616314565b6163146162f883838973ffffffffffffffffffffffffffffffffffffffff16615a15565b8873ffffffffffffffffffffffffffffffffffffffff166169e3565b979650505050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff161161634357600080fd5b6000846fffffffffffffffffffffffffffffffff161161636257600080fd5b81616374576161b585858560016169ee565b6161fc8585856001616b46565b6000808573ffffffffffffffffffffffffffffffffffffffff16116163a557600080fd5b6000846fffffffffffffffffffffffffffffffff16116163c457600080fd5b816163d6576161b58585856000616b46565b6161fc85858560006169ee565b6163eb617659565b600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856fffffffffffffffffffffffffffffffff161161644857600161644a565b845b6fffffffffffffffffffffffffffffffff1673ffffffff00000000000000000000000000000000608085901b168161647e57fe5b0488604001510173ffffffffffffffffffffffffffffffffffffffff16815260200160011515815250915050949350505050565b6164ba617659565b6164c2617659565b888561ffff1661ffff81106164d357fe5b60408051608081018252919092015463ffffffff81168083526401000000008204600690810b810b900b60208401526b010000000000000000000000820473ffffffffffffffffffffffffffffffffffffffff16938301939093527f0100000000000000000000000000000000000000000000000000000000000000900460ff1615156060820152925061656990899089616c7c565b156165a1578663ffffffff16826000015163ffffffff16141561658b576148ec565b81616598838989886163e3565b915091506148ec565b888361ffff168660010161ffff16816165b657fe5b0661ffff1661ffff81106165c657fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b602084015273ffffffffffffffffffffffffffffffffffffffff6b0100000000000000000000008204169183019190915260ff7f0100000000000000000000000000000000000000000000000000000000000000909104161515606082018190529092506166df57604080516080810182528a5463ffffffff811682526401000000008104600690810b810b900b60208301526b010000000000000000000000810473ffffffffffffffffffffffffffffffffffffffff16928201929092527f010000000000000000000000000000000000000000000000000000000000000090910460ff161515606082015291505b6166ee88836000015189616c7c565b61675957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4f4c440000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6167668989898887616d3f565b9150915097509795505050505050565b60006167856009878787615a6d565b60035460045491925090600080600f87900b156169105760006167a6613eba565b60028054600654929350600092839261683592600a928792869274010000000000000000000000000000000000000000810490910b9161ffff7701000000000000000000000000000000000000000000000083048116926fffffffffffffffffffffffffffffffff90921691790100000000000000000000000000000000000000000000000000900416614727565b909250905061686f60078d8b8d8b8b87898b60007f0000000000000000000000000000000000000000000000000000000000000000616f41565b94506168a660078c8b8d8b8b87898b60017f0000000000000000000000000000000000000000000000000000000000000000616f41565b935084156168da576168da60088d7f0000000000000000000000000000000000000000000000000000000000000000617246565b831561690c5761690c60088c7f0000000000000000000000000000000000000000000000000000000000000000617246565b5050505b60008061692260078c8c8b8a8a6172ac565b9092509050616933878a8484617358565b600089600f0b12156169615783156169505761695060078c6175ce565b82156169615761696160078b6175ce565b50505050505095945050505050565b60008082600f0b126169965761699161698c8585856001616207565b6145f5565b6161ff565b6169a961698c8585856000036000616207565b600003949350505050565b60008082600f0b126169d05761699161698c8585856001616134565b6169a961698c8585856000036000616134565b808204910615150190565b60008115616a9657600073ffffffffffffffffffffffffffffffffffffffff841115616a4357616a3e846c01000000000000000000000000876fffffffffffffffffffffffffffffffff16614659565b616a64565b6fffffffffffffffffffffffffffffffff8516606085901b81616a6257fe5b045b9050616a8e616a8973ffffffffffffffffffffffffffffffffffffffff8816836154d1565b6175fa565b9150506161ff565b600073ffffffffffffffffffffffffffffffffffffffff841115616ae357616ade846c01000000000000000000000000876fffffffffffffffffffffffffffffffff16615a15565b616b03565b616b03606085901b6fffffffffffffffffffffffffffffffff87166169e3565b9050808673ffffffffffffffffffffffffffffffffffffffff1611616b2757600080fd5b73ffffffffffffffffffffffffffffffffffffffff86160390506161ff565b600082616b545750836161ff565b7bffffffffffffffffffffffffffffffff000000000000000000000000606085901b168215616c1b5773ffffffffffffffffffffffffffffffffffffffff861684810290858281616ba157fe5b041415616bdf57818101828110616bdd57616bd3838973ffffffffffffffffffffffffffffffffffffffff1683615a15565b93505050506161ff565b505b616c1282616c0d878a73ffffffffffffffffffffffffffffffffffffffff168681616c0657fe5b04906154d1565b6169e3565b925050506161ff565b73ffffffffffffffffffffffffffffffffffffffff861684810290858281616c3f57fe5b04148015616c4c57508082115b616c5557600080fd5b808203616bd3616a898473ffffffffffffffffffffffffffffffffffffffff8b1684615a15565b60008363ffffffff168363ffffffff1611158015616ca657508363ffffffff168263ffffffff1611155b15616cc2578163ffffffff168363ffffffff1611159050614720565b60008463ffffffff168463ffffffff1611616cea578363ffffffff1664010000000001616cf2565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff1611616d23578363ffffffff1664010000000001616d2b565b8363ffffffff165b64ffffffffff169091111595945050505050565b616d47617659565b616d4f617659565b60008361ffff168560010161ffff1681616d6557fe5b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff87168281616d9257fe5b0661ffff8110616d9e57fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b602084015273ffffffffffffffffffffffffffffffffffffffff6b0100000000000000000000008204169183019190915260ff7f010000000000000000000000000000000000000000000000000000000000000090910416151560608201819052909550616e3a57806001019250616d7d565b898661ffff168260010181616e4b57fe5b0661ffff8110616e5757fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b602084015273ffffffffffffffffffffffffffffffffffffffff6b0100000000000000000000008204169183019190915260ff7f010000000000000000000000000000000000000000000000000000000000000090910416151560608201528551909450600090616ef3908b908b616c7c565b9050808015616f0c5750616f0c8a8a8760000151616c7c565b15616f175750616f34565b80616f2757600182039250616f2e565b8160010193505b50616d7d565b5050509550959350505050565b60028a810b900b600090815260208c90526040812080546fffffffffffffffffffffffffffffffff1682616f75828d614a2d565b9050846fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561700a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4c4f000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6fffffffffffffffffffffffffffffffff828116159082161581141594501561715a578c60020b8e60020b1361710e57600183018b9055600283018a90556003830180547fffffffffff0000000000000000000000000000000000000000ffffffffffffff1667010000000000000073ffffffffffffffffffffffffffffffffffffffff8c1602177fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000001666ffffffffffffff60068b900b16177fff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff167b0100000000000000000000000000000000000000000000000000000063ffffffff8a16021790555b6003830180547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790555b82547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff8216178355856171d15782546171cc906171c7907001000000000000000000000000000000009004600f90810b810b908f900b614643565b6156a8565b6171ff565b82546171ff906171c7907001000000000000000000000000000000009004600f90810b810b908f900b614627565b8354600f9190910b6fffffffffffffffffffffffffffffffff9081167001000000000000000000000000000000000291161790925550909c9b505050505050505050505050565b8060020b8260020b8161725557fe5b0760020b1561726357600080fd5b60008061727e8360020b8560020b8161727857fe5b05615e92565b600191820b820b60009081526020979097526040909620805460ff9097169190911b90951890945550505050565b600285810b80820b60009081526020899052604080822088850b850b83529082209193849391929184918291908a900b126172f257505060018201546002830154617305565b8360010154880391508360020154870390505b6000808b60020b8b60020b12156173275750506001830154600284015461733a565b84600101548a0391508460020154890390505b92909803979097039b96909503949094039850939650505050505050565b6040805160a08101825285546fffffffffffffffffffffffffffffffff90811682526001870154602083015260028701549282019290925260038601548083166060830152700100000000000000000000000000000000900490911660808201526000600f85900b61744b5781516fffffffffffffffffffffffffffffffff1661744357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4e50000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b50805161745a565b81516174579086614a2d565b90505b60006174948360200151860384600001516fffffffffffffffffffffffffffffffff16700100000000000000000000000000000000614659565b905060006174d08460400151860385600001516fffffffffffffffffffffffffffffffff16700100000000000000000000000000000000614659565b905086600f0b6000146175185787547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff84161788555b60018801869055600288018590556fffffffffffffffffffffffffffffffff821615158061755857506000816fffffffffffffffffffffffffffffffff16115b156175c4576003880180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821685018216178082167001000000000000000000000000000000009182900483168501909216021790555b5050505050505050565b600290810b810b6000908152602092909252604082208281556001810183905590810182905560030155565b8073ffffffffffffffffffffffffffffffffffffffff81168114613e7157600080fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b6040805160808101825260008082526020820181905291810182905260608101919091529056fea2646970667358221220acd2191725f0d1c2025d7931d90b76815281b45baad28c368b70eff513eea14264736f6c63430007060033"; + "0x6101206040523480156200001257600080fd5b503060601b60805260408051630890357360e41b81529051600091339163890357309160048082019260a092909190829003018186803b1580156200005657600080fd5b505afa1580156200006b573d6000803e3d6000fd5b505050506040513d60a08110156200008257600080fd5b508051602080830151604084015160608086015160809096015160e896871b6001600160e81b03191660c052600180546001600160a01b03199081166001600160a01b039586161790915560008054909116939094169290921790925592901b6001600160601b03191660a052600282810b900b90921b60e0529150620001149082906200012c811b62003de517901c565b60801b6001600160801b03191661010052506200019a565b60008082600281900b620d89e719816200014257fe5b05029050600083600281900b620d89e8816200015a57fe5b0502905060008460020b83830360020b816200017257fe5b0560010190508062ffffff166001600160801b038016816200019057fe5b0495945050505050565b60805160601c60a05160601c60c05160e81c60e05160e81c6101005160801c6176b66200021b60003980612c30528061684b5280616882525080610ed15280613a3052806168b652806168e8525080611039528061236052806123975280613a70525080612d4d528061303e5280613a0c525080613e8e52506176b66000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806370cf754a116100ee578063c45a015511610097578063ddca3f4311610071578063ddca3f43146108bd578063f3058399146108dd578063f30dba93146108e5578063f637731d1461097d576101ae565b8063c45a01551461088e578063d0c93a7c14610896578063d21220a7146108b5576101ae565b8063883bdbfd116100c8578063883bdbfd146106da578063a34123a7146107e3578063a38807f214610826576101ae565b806370cf754a146106575780638206a4d11461065f57806385b6672914610687576101ae565b80633850c7bd1161015b578063490e6cbc11610135578063490e6cbc146104d55780634f1eb3d81461056e578063514ea4bf146105d55780635339c29614610637576101ae565b80633850c7bd1461039d5780633c8a7d8d1461040357806346141319146104bb576101ae565b80631ad8b03b1161018c5780631ad8b03b146102cd578063252c09d71461031657806332148f671461037a576101ae565b80630dfe1681146101b3578063128acb08146101e45780631a686502146102a0575b600080fd5b6101bb6109b0565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610287600480360360a08110156101fa57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135151592604082013592606083013516919081019060a08101608082013564010000000081111561024857600080fd5b82018360208201111561025a57600080fd5b8035906020019184600183028401116401000000008311171561027c57600080fd5b5090925090506109cc565b6040805192835260208301919091528051918290030190f35b6102a8611a6f565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102d5611a87565b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6103336004803603602081101561032c57600080fd5b5035611ab7565b6040805163ffffffff909516855260069390930b602085015273ffffffffffffffffffffffffffffffffffffffff9091168383015215156060830152519081900360800190f35b61039b6004803603602081101561039057600080fd5b503561ffff16611b2e565b005b6103a5611d12565b6040805173ffffffffffffffffffffffffffffffffffffffff909816885260029690960b602088015261ffff9485168787015292841660608701529216608085015260ff90911660a0840152151560c0830152519081900360e00190f35b610287600480360360a081101561041957600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516916020810135600290810b92604083013590910b916fffffffffffffffffffffffffffffffff6060820135169181019060a08101608082013564010000000081111561047c57600080fd5b82018360208201111561048e57600080fd5b803590602001918460018302840111640100000000831117156104b057600080fd5b509092509050611df7565b6104c361220e565b60408051918252519081900360200190f35b61039b600480360360808110156104eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516916020810135916040820135919081019060808101606082013564010000000081111561052f57600080fd5b82018360208201111561054157600080fd5b8035906020019184600183028401116401000000008311171561056357600080fd5b509092509050612214565b6102d5600480360360a081101561058457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020810135600290810b91604081013590910b906fffffffffffffffffffffffffffffffff6060820135811691608001351661287a565b6105f2600480360360208110156105eb57600080fd5b5035612bc9565b604080516fffffffffffffffffffffffffffffffff96871681526020810195909552848101939093529084166060840152909216608082015290519081900360a00190f35b6104c36004803603602081101561064d57600080fd5b503560010b612c1c565b6102a8612c2e565b61039b6004803603604081101561067557600080fd5b5060ff81358116916020013516612c52565b6102d56004803603606081101561069d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906fffffffffffffffffffffffffffffffff60208201358116916040013516612f3e565b61074a600480360360208110156106f057600080fd5b81019060208101813564010000000081111561070b57600080fd5b82018360208201111561071d57600080fd5b8035906020019184602083028401116401000000008311171561073f57600080fd5b5090925090506133cc565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561078e578181015183820152602001610776565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156107cd5781810151838201526020016107b5565b5050505090500194505050505060405180910390f35b610287600480360360608110156107f957600080fd5b508035600290810b91602081013590910b90604001356fffffffffffffffffffffffffffffffff1661349f565b6108506004803603604081101561083c57600080fd5b508035600290810b9160200135900b6136f7565b6040805160069490940b845273ffffffffffffffffffffffffffffffffffffffff909216602084015263ffffffff1682820152519081900360600190f35b6101bb613a0a565b61089e613a2e565b6040805160029290920b8252519081900360200190f35b6101bb613a52565b6108c5613a6e565b6040805162ffffff9092168252519081900360200190f35b6104c3613a92565b610905600480360360208110156108fb57600080fd5b503560020b613a98565b604080516fffffffffffffffffffffffffffffffff9099168952600f9790970b602089015287870195909552606087019390935260069190910b608086015273ffffffffffffffffffffffffffffffffffffffff1660a085015263ffffffff1660c0840152151560e083015251908190036101000190f35b61039b6004803603602081101561099357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613b5d565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6000806109d7613e76565b85610a4357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4153000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6040805160e0810182526002805473ffffffffffffffffffffffffffffffffffffffff81168352740100000000000000000000000000000000000000008104820b820b90910b602083015261ffff7701000000000000000000000000000000000000000000000082048116938301939093527901000000000000000000000000000000000000000000000000008104831660608301527b010000000000000000000000000000000000000000000000000000008104909216608082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660a08301527e01000000000000000000000000000000000000000000000000000000000000909204909116151560c08201819052610bc457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b87610c3657806000015173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16118015610c31575073fffd8963efd1fc6a506488495d951d5263988d2673ffffffffffffffffffffffffffffffffffffffff8716105b610c8f565b806000015173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16108015610c8f57506401000276a373ffffffffffffffffffffffffffffffffffffffff8716115b610cfa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53504c0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040805160c08101909152600090808a610d475760048460a0015160ff16901c610d5a565b60108460a0015160ff1681610d5857fe5b065b60ff1681526006546fffffffffffffffffffffffffffffffff166020820152604001610d84613eba565b63ffffffff168152602001600060060b8152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000151581525090506000808913905060006040518060e001604052808b815260200160008152602001856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015160020b81526020018c610e1a57600454610e1e565b6003545b815260200160006fffffffffffffffffffffffffffffffff16815260200184602001516fffffffffffffffffffffffffffffffff1681525090505b805115801590610e9957508873ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1614155b1561136857610ea661761d565b604082015173ffffffffffffffffffffffffffffffffffffffff1681526060820151610ef6906008907f00000000000000000000000000000000000000000000000000000000000000008f613ebe565b15156040830152600290810b810b602083018190527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618910b1215610f5f577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276186020820152610f7e565b6020810151620d89e860029190910b1315610f7e57620d89e860208201525b610f8b816020015161403c565b73ffffffffffffffffffffffffffffffffffffffff166060820152604082015161105d908d610fec578b73ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff1611611020565b8b73ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16105b61102e578260600151611030565b8b5b60c085015185517f00000000000000000000000000000000000000000000000000000000000000006143cf565b60c085015260a0840152608083015273ffffffffffffffffffffffffffffffffffffffff16604083015282156110cc576110a08160c001518260800151016145f5565b825103825260a08101516110c2906110b7906145f5565b602084015190614627565b6020830152611107565b6110d98160a001516145f5565b825101825260c08101516080820151611101916110f691016145f5565b602084015190614643565b60208301525b835160ff1615611156576000846000015160ff168260c001518161112757fe5b60c0840180519290910491829003905260a0840180519091016fffffffffffffffffffffffffffffffff169052505b60c08201516fffffffffffffffffffffffffffffffff16156111b4576111a88160c001517001000000000000000000000000000000008460c001516fffffffffffffffffffffffffffffffff16614659565b60808301805190910190525b806060015173ffffffffffffffffffffffffffffffffffffffff16826040015173ffffffffffffffffffffffffffffffffffffffff16141561130d578060400151156112e4578360a0015161126557611236846040015160008760200151886040015188602001518a60600151600a614727909695949392919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff166080860152600690810b900b6060850152600160a08501525b60006112b182602001518e61127c57600354611282565b84608001515b8f611291578560800151611295565b6004545b608089015160608a015160408b015160079594939291906148f8565b90508c156112bd576000035b6112cb8360c0015182614a2d565b6fffffffffffffffffffffffffffffffff1660c0840152505b8b6112f35780602001516112fc565b60018160200151035b600290810b900b6060830152611362565b806000015173ffffffffffffffffffffffffffffffffffffffff16826040015173ffffffffffffffffffffffffffffffffffffffff1614611362576113558260400151614b71565b600290810b900b60608301525b50610e59565b836020015160020b816060015160020b146114e0576000806113b686604001518660400151886020015188602001518a606001518b60800151600a614f3d909695949392919063ffffffff16565b60408501516060860151600280547fffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff1679010000000000000000000000000000000000000000000000000061ffff95861602177fffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000009590941694909402929092177fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000062ffffff93850b9390931692909202919091177fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161790555061152a9050565b6040810151600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790555b8060c001516fffffffffffffffffffffffffffffffff1683602001516fffffffffffffffffffffffffffffffff16146115a35760c0810151600680547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9092169190911790555b8a1561161d57608081015160035560a08101516fffffffffffffffffffffffffffffffff16156116185760a0810151600580547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff918216909301169190911790555b611682565b608081015160045560a08101516fffffffffffffffffffffffffffffffff16156116825760a0810151600580546fffffffffffffffffffffffffffffffff80821670010000000000000000000000000000000092839004821690940116029190911790555b8115158b15151461169b57602081015181518b036116a8565b80600001518a0381602001515b90965094508a1561181c5760008512156116e4576001546116e49073ffffffffffffffffffffffffffffffffffffffff168d6000889003615183565b60006116ee61535f565b90503373ffffffffffffffffffffffffffffffffffffffff1663fa461e3388888c8c6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561177f57600080fd5b505af1158015611793573d6000803e3d6000fd5b5050505061179f61535f565b6117a982896154d1565b111561181657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4949410000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b50611987565b60008612156118535761185360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d88600003615183565b600061185d6154e1565b90503373ffffffffffffffffffffffffffffffffffffffff1663fa461e3388888c8c6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156118ee57600080fd5b505af1158015611902573d6000803e3d6000fd5b5050505061190e6154e1565b61191882886154d1565b111561198557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4949410000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b505b60408082015160c083015160608085015184518b8152602081018b905273ffffffffffffffffffffffffffffffffffffffff948516818701526fffffffffffffffffffffffffffffffff9093169183019190915260020b60808201529151908e169133917fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679181900360a00190a35050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550919890975095505050505050565b6006546fffffffffffffffffffffffffffffffff1681565b6005546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041682565b600a8161ffff8110611ac857600080fd5b015463ffffffff81169150640100000000810460060b906b010000000000000000000000810473ffffffffffffffffffffffffffffffffffffffff16907f0100000000000000000000000000000000000000000000000000000000000000900460ff1684565b6002547e01000000000000000000000000000000000000000000000000000000000000900460ff16611bc157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055611bf1613e76565b6002547b01000000000000000000000000000000000000000000000000000000900461ffff166000611c25600a83856155b4565b6002805461ffff8084167b0100000000000000000000000000000000000000000000000000000081027fffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff90931692909217909255919250831614611cc4576040805161ffff80851682528316602082015281517fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a929181900390910190a15b5050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550565b6002805473ffffffffffffffffffffffffffffffffffffffff811691740100000000000000000000000000000000000000008204900b9061ffff77010000000000000000000000000000000000000000000000820481169179010000000000000000000000000000000000000000000000000081048216917b010000000000000000000000000000000000000000000000000000008204169060ff7d01000000000000000000000000000000000000000000000000000000000082048116917e0100000000000000000000000000000000000000000000000000000000000090041687565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff16611e8f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556fffffffffffffffffffffffffffffffff8516611ed357600080fd5b600080611f3760405180608001604052808c73ffffffffffffffffffffffffffffffffffffffff1681526020018b60020b81526020018a60020b8152602001611f2d8a6fffffffffffffffffffffffffffffffff166156a8565b600f0b90526156b9565b92509250508193508092506000806000861115611f5957611f5661535f565b91505b8415611f6a57611f676154e1565b90505b3373ffffffffffffffffffffffffffffffffffffffff1663d348799787878b8b6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611ff957600080fd5b505af115801561200d573d6000803e3d6000fd5b5050505060008611156120995761202261535f565b61202c83886154d1565b111561209957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4d30000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b841561211e576120a76154e1565b6120b182876154d1565b111561211e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4d31000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8960020b8b60020b8d73ffffffffffffffffffffffffffffffffffffffff167f7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde338d8b8b604051808573ffffffffffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a45050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550919890975095505050505050565b60045481565b6002547e01000000000000000000000000000000000000000000000000000000000000900460ff166122a757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556122d7613e76565b6006546fffffffffffffffffffffffffffffffff168061235857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f4c00000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600061238d867f000000000000000000000000000000000000000000000000000000000000000062ffffff16620f4240615a15565b905060006123c4867f000000000000000000000000000000000000000000000000000000000000000062ffffff16620f4240615a15565b905060006123d061535f565b905060006123dc6154e1565b90508815612408576000546124089073ffffffffffffffffffffffffffffffffffffffff168b8b615183565b8715612432576001546124329073ffffffffffffffffffffffffffffffffffffffff168b8a615183565b3373ffffffffffffffffffffffffffffffffffffffff1663e9cbafb085858a8a6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156124c157600080fd5b505af11580156124d5573d6000803e3d6000fd5b5050505060006124e361535f565b905060006124ef6154e1565b9050816124fc85886154d1565b111561256957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4630000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8061257484876154d1565b11156125e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4631000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b83820383820381156126ca576002547d0100000000000000000000000000000000000000000000000000000000009004600f166000811561262e578160ff16848161262857fe5b04612631565b60005b90506fffffffffffffffffffffffffffffffff81161561268e57600580546fffffffffffffffffffffffffffffffff8082168401167fffffffffffffffffffffffffffffffff000000000000000000000000000000009091161790555b6126be8185037001000000000000000000000000000000008d6fffffffffffffffffffffffffffffffff16614659565b60038054909101905550505b80156127a4576002547d010000000000000000000000000000000000000000000000000000000000900460041c600f1660008115612714578160ff16838161270e57fe5b04612717565b60005b90506fffffffffffffffffffffffffffffffff81161561276857600580546fffffffffffffffffffffffffffffffff7001000000000000000000000000000000008083048216850182160291161790555b6127988184037001000000000000000000000000000000008d6fffffffffffffffffffffffffffffffff16614659565b60048054909101905550505b8d73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca6338f8f86866040518085815260200184815260200183815260200182815260200194505050505060405180910390a35050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055505050505050505050505050565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff1661291257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905560006129496009338989615a6d565b60038101549091506fffffffffffffffffffffffffffffffff90811690861611612973578461298b565b60038101546fffffffffffffffffffffffffffffffff165b60038201549093506fffffffffffffffffffffffffffffffff7001000000000000000000000000000000009091048116908516116129c957836129f5565b600381015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b91506fffffffffffffffffffffffffffffffff831615612a7e576003810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff918216869003821617909155600054612a7e9173ffffffffffffffffffffffffffffffffffffffff909116908a908616615183565b6fffffffffffffffffffffffffffffffff821615612afd576003810180546fffffffffffffffffffffffffffffffff700100000000000000000000000000000000808304821686900382160291811691909117909155600154612afd9173ffffffffffffffffffffffffffffffffffffffff909116908a908516615183565b6040805173ffffffffffffffffffffffffffffffffffffffff8a1681526fffffffffffffffffffffffffffffffff80861660208301528416818301529051600288810b92908a900b9133917f70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0919081900360600190a450600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905590969095509350505050565b60096020526000908152604090208054600182015460028301546003909301546fffffffffffffffffffffffffffffffff9283169391928181169170010000000000000000000000000000000090041685565b60086020526000908152604090205481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6002547e01000000000000000000000000000000000000000000000000000000000000900460ff16612ce557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691638da5cb5b916004808301926020929190829003018186803b158015612d9357600080fd5b505afa158015612da7573d6000803e3d6000fd5b505050506040513d6020811015612dbd57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612de057600080fd5b60ff82161580612e03575060048260ff1610158015612e035750600a8260ff1611155b8015612e2d575060ff81161580612e2d575060048160ff1610158015612e2d5750600a8160ff1611155b612e3657600080fd5b60028054610ff0600484901b16840160ff9081167d0100000000000000000000000000000000000000000000000000000000009081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841617909355919004167f973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b1336010826040805160ff9390920683168252600f600486901c16602083015286831682820152918516606082015290519081900360800190a15050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905550565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff16612fd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691638da5cb5b916004808301926020929190829003018186803b15801561308457600080fd5b505afa158015613098573d6000803e3d6000fd5b505050506040513d60208110156130ae57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1633146130d157600080fd5b6005546fffffffffffffffffffffffffffffffff908116908516116130f6578361310c565b6005546fffffffffffffffffffffffffffffffff165b6005549092506fffffffffffffffffffffffffffffffff7001000000000000000000000000000000009091048116908416116131485782613172565b60055470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b90506fffffffffffffffffffffffffffffffff82161561323e576005546fffffffffffffffffffffffffffffffff838116911614156131d1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b600580547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821685900382161790915560005461323e9173ffffffffffffffffffffffffffffffffffffffff9091169087908516615183565b6fffffffffffffffffffffffffffffffff811615613311576005546fffffffffffffffffffffffffffffffff8281167001000000000000000000000000000000009092041614156132ac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff015b600580546fffffffffffffffffffffffffffffffff7001000000000000000000000000000000008083048216859003821602918116919091179091556001546133119173ffffffffffffffffffffffffffffffffffffffff9091169087908416615183565b604080516fffffffffffffffffffffffffffffffff808516825283166020820152815173ffffffffffffffffffffffffffffffffffffffff88169233927f596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151929081900390910190a3600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790559094909350915050565b6060806133d7613e76565b6134946133e2613eba565b8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060028054600654600a9695945074010000000000000000000000000000000000000000820490920b925061ffff7701000000000000000000000000000000000000000000000082048116926fffffffffffffffffffffffffffffffff1691790100000000000000000000000000000000000000000000000000900416615ae4565b915091509250929050565b60025460009081907e01000000000000000000000000000000000000000000000000000000000000900460ff1661353757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4c4f4b0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681556040805160808101825233815287830b60208201529186900b90820152600090819081906135b390606081016135a66fffffffffffffffffffffffffffffffff8a166156a8565b600003600f0b90526156b9565b92509250925081600003945080600003935060008511806135d45750600084115b15613641576003830180546fffffffffffffffffffffffffffffffff808216808901821670010000000000000000000000000000000093849004831689019092169092029091177fffffffffffffffffffffffffffffffff00000000000000000000000000000000161790555b604080516fffffffffffffffffffffffffffffffff88168152602081018790528082018690529051600289810b92908b900b9133917f0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c919081900360600190a45050600280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055509094909350915050565b6000806000613704613e76565b61370e8585615c8e565b600285810b810b60009081526007602052604080822087840b90930b825281206003830154600681900b93670100000000000000820473ffffffffffffffffffffffffffffffffffffffff169284927b01000000000000000000000000000000000000000000000000000000810463ffffffff1692849290917f0100000000000000000000000000000000000000000000000000000000000000900460ff16806137b757600080fd5b6003820154600681900b9850670100000000000000810473ffffffffffffffffffffffffffffffffffffffff1696507b01000000000000000000000000000000000000000000000000000000810463ffffffff1694507f0100000000000000000000000000000000000000000000000000000000000000900460ff168061383d57600080fd5b50506040805160e0810182526002805473ffffffffffffffffffffffffffffffffffffffff81168352740100000000000000000000000000000000000000008104820b820b820b6020840181905261ffff7701000000000000000000000000000000000000000000000083048116958501959095527901000000000000000000000000000000000000000000000000008204851660608501527b010000000000000000000000000000000000000000000000000000008204909416608084015260ff7d0100000000000000000000000000000000000000000000000000000000008204811660a08501527e0100000000000000000000000000000000000000000000000000000000000090910416151560c08301529093508e810b91900b1215905061397757509390940396509003935090039050613a03565b8a60020b816020015160020b12156139f4576000613993613eba565b60208301516040840151600654606086015193945060009384936139d293600a938893879392916fffffffffffffffffffffffffffffffff1690614727565b9a9003989098039b505094909603929092039650909103039250613a03915050565b50949093039650039350900390505b9250925092565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b60076020526000908152604090208054600182015460028301546003909301546fffffffffffffffffffffffffffffffff831693700100000000000000000000000000000000909304600f0b9290600681900b90670100000000000000810473ffffffffffffffffffffffffffffffffffffffff16907b01000000000000000000000000000000000000000000000000000000810463ffffffff16907f0100000000000000000000000000000000000000000000000000000000000000900460ff1688565b60025473ffffffffffffffffffffffffffffffffffffffff1615613be257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4149000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000613bed82614b71565b9050600080613c05613bfd613eba565b600a90615e0f565b6040805160e08101825273ffffffffffffffffffffffffffffffffffffffff8816808252600288810b6020808501829052600085870181905261ffff898116606088018190529089166080880181905260a0880192909252600160c09097019690965283547e010000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffff000000000000000000000000000000000000000090911686177fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000062ffffff86880b1602177fffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffff16790100000000000000000000000000000000000000000000000000909702969096177fffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff167b01000000000000000000000000000000000000000000000000000000909102177fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169490941790915583519182529181019190915281519395509193507f98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c9592918290030190a150505050565b60008082600281900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761881613e1657fe5b05029050600083600281900b620d89e881613e2d57fe5b0502905060008460020b83830360020b81613e4457fe5b0560010190508062ffffff166fffffffffffffffffffffffffffffffff801681613e6a57fe5b0493505050505b919050565b3073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614613eb857600080fd5b565b4290565b60008060008460020b8660020b81613ed257fe5b05905060008660020b128015613ef957508460020b8660020b81613ef257fe5b0760020b15155b15613f21577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff015b8315613fb457600080613f3383615e92565b600182810b810b600090815260208d9052604090205460ff83169190911b80017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190811680151597509294509092509085613f9657888360ff16860302613fa9565b88613fa082615ea4565b840360ff168603025b965050505050614032565b600080613fc383600101615e92565b91509150600060018260ff166001901b031990506000818b60008660010b60010b815260200190815260200160002054169050806000141595508561401557888360ff0360ff1686600101010261402b565b888361402083615f51565b0360ff168660010101025b9650505050505b5094509492505050565b60008060008360020b12614053578260020b61405b565b8260020b6000035b9050620d89e88111156140cf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f5400000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000600182166140f057700100000000000000000000000000000000614102565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615614136576ffff97272373d413259a46990580e213a0260801c5b6004821615614155576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614174576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615614193576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156141b2576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156141d1576fff2ea16466c96a3843ec78b326b528610260801c5b60808216156141f0576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615614210576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615614230576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615614250576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615614270576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615614290576fd097f3bdfd2022b8845ad8f792aa58250260801c5b6120008216156142b0576fa9f746462d870fdf8a65dc1f90e061e50260801c5b6140008216156142d0576f70d869a156d2a1b890bb3df62baf32f70260801c5b6180008216156142f0576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615614311576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615614331576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615614350576d2216e584f5fa1ea926041bedfe980260801c5b6208000082161561436d576b048a170391f7dc42444e8fa20260801c5b60008460020b13156143a657807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff816143a257fe5b0490505b6401000000008106156143ba5760016143bd565b60005b60ff16602082901c0192505050919050565b600080808073ffffffffffffffffffffffffffffffffffffffff808916908a1610158187128015906144615760006144158989620f42400362ffffff16620f4240614659565b90508261442e576144298c8c8c6001616134565b61443b565b61443b8b8d8c6001616207565b955085811061444c578a965061445b565b6144588c8b838661631f565b96505b506144ab565b81614478576144738b8b8b6000616207565b614485565b6144858a8c8b6000616134565b9350838860000310614499578995506144ab565b6144a88b8a8a60000385616381565b95505b73ffffffffffffffffffffffffffffffffffffffff8a811690871614821561451b578080156144d75750815b6144ed576144e8878d8c6001616207565b6144ef565b855b95508080156144fc575081155b6145125761450d878d8c6000616134565b614514565b845b9450614565565b8080156145255750815b61453b576145368c888c6001616134565b61453d565b855b955080801561454a575081155b6145605761455b8c888c6000616207565b614562565b845b94505b8115801561457557508860000385115b15614581578860000394505b8180156145ba57508a73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b156145c95785890393506145e6565b6145e3868962ffffff168a620f42400362ffffff16615a15565b93505b50505095509550955095915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821061462357600080fd5b5090565b8082038281131560008312151461463d57600080fd5b92915050565b8181018281121560008312151461463d57600080fd5b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff858709868602925082811090839003039050806146ad57600084116146a257600080fd5b508290049050614720565b8084116146b957600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150505b9392505050565b60008063ffffffff87166147ff576000898661ffff1661ffff811061474857fe5b60408051608081018252919092015463ffffffff8082168084526401000000008304600690810b810b900b60208501526b010000000000000000000000830473ffffffffffffffffffffffffffffffffffffffff16948401949094527f010000000000000000000000000000000000000000000000000000000000000090910460ff16151560608301529092508a16146147eb576147e8818a89886163e3565b90505b8060200151816040015192509250506148ec565b8688036000806148148c8c858c8c8c8c6164b2565b91509150816000015163ffffffff168363ffffffff1614156148465781602001518260400151945094505050506148ec565b805163ffffffff8481169116141561486e5780602001518160400151945094505050506148ec565b8151815160208085015190840151918390039286039163ffffffff80841692908516910360060b8161489c57fe5b05028460200151018263ffffffff168263ffffffff16866040015186604001510373ffffffffffffffffffffffffffffffffffffffff1602816148db57fe5b048560400151019650965050505050505b97509795505050505050565b600295860b860b60009081526020979097526040909620600181018054909503909455938301805490920390915560038201805463ffffffff7b0100000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff6701000000000000008085048216909603169094027fffffffffff0000000000000000000000000000000000000000ffffffffffffff90921691909117600681810b90960390950b66ffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000909516949094178281048516909503909316027fff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff909316929092179055547001000000000000000000000000000000009004600f0b90565b60008082600f0b1215614ad957826fffffffffffffffffffffffffffffffff168260000384039150816fffffffffffffffffffffffffffffffff1610614ad457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4c53000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61463d565b826fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff16101561463d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4c41000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60006401000276a373ffffffffffffffffffffffffffffffffffffffff831610801590614bc7575073fffd8963efd1fc6a506488495d951d5263988d2673ffffffffffffffffffffffffffffffffffffffff8316105b614c3257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f5200000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b77ffffffffffffffffffffffffffffffffffffffff00000000602083901b166fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c97908811961790941790921717909117171760808110614cdc57607f810383901c9150614ce6565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808f0160401b60c09190911c678000000000000000161760c19b909b1c674000000000000000169a909a1760c29990991c672000000000000000169890981760c39790971c671000000000000000169690961760c49590951c670800000000000000169490941760c59390931c670400000000000000169290921760c69190911c670200000000000000161760c79190911c670100000000000000161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617693627a301d71055774c8581027ffffffffffffffffffffffffffffffffffd709b7e5480fba5a50fed5e62ffc5568101608090811d906fdb2df09e81959a81455e260799a0632f8301901d600281810b9083900b14614f2e578873ffffffffffffffffffffffffffffffffffffffff16614f058261403c565b73ffffffffffffffffffffffffffffffffffffffff161115614f275781614f29565b805b614f30565b815b9998505050505050505050565b6000806000898961ffff1661ffff8110614f5357fe5b60408051608081018252919092015463ffffffff8082168084526401000000008304600690810b810b900b60208501526b010000000000000000000000830473ffffffffffffffffffffffffffffffffffffffff16948401949094527f010000000000000000000000000000000000000000000000000000000000000090910460ff161515606083015290925089161415614ff457888592509250506148ec565b8461ffff168461ffff1611801561501557506001850361ffff168961ffff16145b1561502257839150615026565b8491505b8161ffff168960010161ffff168161503a57fe5b069250615049818989896163e3565b8a8461ffff1661ffff811061505a57fe5b8251910180546020840151604085015160609095015115157f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff9096166b010000000000000000000000027fff0000000000000000000000000000000000000000ffffffffffffffffffffff60069390930b66ffffffffffffff16640100000000027fffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff63ffffffff9097167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009095169490941795909516929092171692909217929092161790555097509795505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061525857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161521b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146152ba576040519150601f19603f3d011682016040523d82523d6000602084013e6152bf565b606091505b50915091508180156152ed5750805115806152ed57508080602001905160208110156152ea57600080fd5b50515b61535857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5446000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b60008054604080513060248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a0823100000000000000000000000000000000000000000000000000000000178152915181518594859473ffffffffffffffffffffffffffffffffffffffff9091169392918291908083835b6020831061543157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016153f4565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615491576040519150601f19603f3d011682016040523d82523d6000602084013e615496565b606091505b50915091508180156154aa57506020815110155b6154b357600080fd5b8080602001905160208110156154c857600080fd5b50519250505090565b8082018281101561463d57600080fd5b600154604080513060248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a0823100000000000000000000000000000000000000000000000000000000178152915181516000948594859473ffffffffffffffffffffffffffffffffffffffff9092169391928291908083836020831061543157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016153f4565b6000808361ffff161161562857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f4900000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8261ffff168261ffff161161563e575081614720565b825b8261ffff168161ffff16101561569f576001858261ffff1661ffff811061566357fe5b0180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff92909216919091179055600101615640565b50909392505050565b80600f81900b8114613e7157600080fd5b60008060006156c6613e76565b6156d884602001518560400151615c8e565b6040805160e0810182526002805473ffffffffffffffffffffffffffffffffffffffff81168352740100000000000000000000000000000000000000008104820b820b90910b602080840182905261ffff770100000000000000000000000000000000000000000000008404811685870152790100000000000000000000000000000000000000000000000000840481166060808701919091527b010000000000000000000000000000000000000000000000000000008504909116608086015260ff7d0100000000000000000000000000000000000000000000000000000000008504811660a08701527e01000000000000000000000000000000000000000000000000000000000000909404909316151560c0850152885190890151948901519289015193946158109491939092909190616776565b93508460600151600f0b600014615a0d57846020015160020b816020015160020b12156158655761585e615847866020015161403c565b615854876040015161403c565b8760600151616970565b9250615a0d565b846040015160020b816020015160020b12156159e35760065460408201516fffffffffffffffffffffffffffffffff909116906158c0906158a4613eba565b602085015160608601516080870151600a949392918791614f3d565b600280547fffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff1679010000000000000000000000000000000000000000000000000061ffff93841602177fffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff167701000000000000000000000000000000000000000000000093909216929092021790558151604087015161596e91906159649061403c565b8860600151616970565b935061598c615980876020015161403c565b835160608901516169b4565b925061599c818760600151614a2d565b600680547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691909117905550615a0d565b615a0a6159f3866020015161403c565b615a00876040015161403c565b87606001516169b4565b91505b509193909250565b6000615a22848484614659565b905060008280615a2e57fe5b8486091115614720577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110615a6357600080fd5b6001019392505050565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080860191909152600293840b60e890811b60348701529290930b90911b60378401528051808403601a018152603a90930181528251928201929092206000908152929052902090565b60608060008361ffff1611615b5a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f4900000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b865167ffffffffffffffff81118015615b7257600080fd5b50604051908082528060200260200182016040528015615b9c578160200160208202803683370190505b509150865167ffffffffffffffff81118015615bb757600080fd5b50604051908082528060200260200182016040528015615be1578160200160208202803683370190505b50905060005b8751811015615c8157615c128a8a8a8481518110615c0157fe5b60200260200101518a8a8a8a614727565b848381518110615c1e57fe5b60200260200101848481518110615c3157fe5b602002602001018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152508260060b60060b81525050508080600101915050615be7565b5097509795505050505050565b8060020b8260020b12615d0257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f544c550000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618600283900b1215615d9557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f544c4d0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b620d89e8600282900b1315615e0b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f54554d0000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b5050565b6040805160808101825263ffffffff928316808252600060208301819052928201929092526001606090910181905283547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000169091179091167f010000000000000000000000000000000000000000000000000000000000000017909155908190565b60020b600881901d9161010090910790565b6000808211615eb257600080fd5b7001000000000000000000000000000000008210615ed257608091821c91015b680100000000000000008210615eea57604091821c91015b6401000000008210615efe57602091821c91015b620100008210615f1057601091821c91015b6101008210615f2157600891821c91015b60108210615f3157600491821c91015b60048210615f4157600291821c91015b60028210613e7157600101919050565b6000808211615f5f57600080fd5b5060ff6fffffffffffffffffffffffffffffffff821615615fa1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8001615fa9565b608082901c91505b67ffffffffffffffff821615615fe0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001615fe8565b604082901c91505b63ffffffff82161561601b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001616023565b602082901c91505b61ffff821615616054577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00161605c565b601082901c91505b60ff82161561608c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff801616094565b600882901c91505b600f8216156160c4577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc016160cc565b600482901c91505b60038216156160fc577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01616104565b600282901c91505b6001821615613e71577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01919050565b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561616e579293925b816161ba576161b5836fffffffffffffffffffffffffffffffff1686860373ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000614659565b6161fc565b6161fc836fffffffffffffffffffffffffffffffff1686860373ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000615a15565b90505b949350505050565b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115616241579293925b7bffffffffffffffffffffffffffffffff000000000000000000000000606084901b1673ffffffffffffffffffffffffffffffffffffffff868603811690871661628a57600080fd5b836162d4578673ffffffffffffffffffffffffffffffffffffffff166162c783838973ffffffffffffffffffffffffffffffffffffffff16614659565b816162ce57fe5b04616314565b6163146162f883838973ffffffffffffffffffffffffffffffffffffffff16615a15565b8873ffffffffffffffffffffffffffffffffffffffff166169e3565b979650505050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff161161634357600080fd5b6000846fffffffffffffffffffffffffffffffff161161636257600080fd5b81616374576161b585858560016169ee565b6161fc8585856001616b46565b6000808573ffffffffffffffffffffffffffffffffffffffff16116163a557600080fd5b6000846fffffffffffffffffffffffffffffffff16116163c457600080fd5b816163d6576161b58585856000616b46565b6161fc85858560006169ee565b6163eb617659565b600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856fffffffffffffffffffffffffffffffff161161644857600161644a565b845b6fffffffffffffffffffffffffffffffff1673ffffffff00000000000000000000000000000000608085901b168161647e57fe5b0488604001510173ffffffffffffffffffffffffffffffffffffffff16815260200160011515815250915050949350505050565b6164ba617659565b6164c2617659565b888561ffff1661ffff81106164d357fe5b60408051608081018252919092015463ffffffff81168083526401000000008204600690810b810b900b60208401526b010000000000000000000000820473ffffffffffffffffffffffffffffffffffffffff16938301939093527f0100000000000000000000000000000000000000000000000000000000000000900460ff1615156060820152925061656990899089616c7c565b156165a1578663ffffffff16826000015163ffffffff16141561658b576148ec565b81616598838989886163e3565b915091506148ec565b888361ffff168660010161ffff16816165b657fe5b0661ffff1661ffff81106165c657fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b602084015273ffffffffffffffffffffffffffffffffffffffff6b0100000000000000000000008204169183019190915260ff7f0100000000000000000000000000000000000000000000000000000000000000909104161515606082018190529092506166df57604080516080810182528a5463ffffffff811682526401000000008104600690810b810b900b60208301526b010000000000000000000000810473ffffffffffffffffffffffffffffffffffffffff16928201929092527f010000000000000000000000000000000000000000000000000000000000000090910460ff161515606082015291505b6166ee88836000015189616c7c565b61675957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f4f4c440000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6167668989898887616d3f565b9150915097509795505050505050565b60006167856009878787615a6d565b60035460045491925090600080600f87900b156169105760006167a6613eba565b60028054600654929350600092839261683592600a928792869274010000000000000000000000000000000000000000810490910b9161ffff7701000000000000000000000000000000000000000000000083048116926fffffffffffffffffffffffffffffffff90921691790100000000000000000000000000000000000000000000000000900416614727565b909250905061686f60078d8b8d8b8b87898b60007f0000000000000000000000000000000000000000000000000000000000000000616f41565b94506168a660078c8b8d8b8b87898b60017f0000000000000000000000000000000000000000000000000000000000000000616f41565b935084156168da576168da60088d7f0000000000000000000000000000000000000000000000000000000000000000617246565b831561690c5761690c60088c7f0000000000000000000000000000000000000000000000000000000000000000617246565b5050505b60008061692260078c8c8b8a8a6172ac565b9092509050616933878a8484617358565b600089600f0b12156169615783156169505761695060078c6175ce565b82156169615761696160078b6175ce565b50505050505095945050505050565b60008082600f0b126169965761699161698c8585856001616207565b6145f5565b6161ff565b6169a961698c8585856000036000616207565b600003949350505050565b60008082600f0b126169d05761699161698c8585856001616134565b6169a961698c8585856000036000616134565b808204910615150190565b60008115616a9657600073ffffffffffffffffffffffffffffffffffffffff841115616a4357616a3e846c01000000000000000000000000876fffffffffffffffffffffffffffffffff16614659565b616a64565b6fffffffffffffffffffffffffffffffff8516606085901b81616a6257fe5b045b9050616a8e616a8973ffffffffffffffffffffffffffffffffffffffff8816836154d1565b6175fa565b9150506161ff565b600073ffffffffffffffffffffffffffffffffffffffff841115616ae357616ade846c01000000000000000000000000876fffffffffffffffffffffffffffffffff16615a15565b616b03565b616b03606085901b6fffffffffffffffffffffffffffffffff87166169e3565b9050808673ffffffffffffffffffffffffffffffffffffffff1611616b2757600080fd5b73ffffffffffffffffffffffffffffffffffffffff86160390506161ff565b600082616b545750836161ff565b7bffffffffffffffffffffffffffffffff000000000000000000000000606085901b168215616c1b5773ffffffffffffffffffffffffffffffffffffffff861684810290858281616ba157fe5b041415616bdf57818101828110616bdd57616bd3838973ffffffffffffffffffffffffffffffffffffffff1683615a15565b93505050506161ff565b505b616c1282616c0d878a73ffffffffffffffffffffffffffffffffffffffff168681616c0657fe5b04906154d1565b6169e3565b925050506161ff565b73ffffffffffffffffffffffffffffffffffffffff861684810290858281616c3f57fe5b04148015616c4c57508082115b616c5557600080fd5b808203616bd3616a898473ffffffffffffffffffffffffffffffffffffffff8b1684615a15565b60008363ffffffff168363ffffffff1611158015616ca657508363ffffffff168263ffffffff1611155b15616cc2578163ffffffff168363ffffffff1611159050614720565b60008463ffffffff168463ffffffff1611616cea578363ffffffff1664010000000001616cf2565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff1611616d23578363ffffffff1664010000000001616d2b565b8363ffffffff165b64ffffffffff169091111595945050505050565b616d47617659565b616d4f617659565b60008361ffff168560010161ffff1681616d6557fe5b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff87168281616d9257fe5b0661ffff8110616d9e57fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b602084015273ffffffffffffffffffffffffffffffffffffffff6b0100000000000000000000008204169183019190915260ff7f010000000000000000000000000000000000000000000000000000000000000090910416151560608201819052909550616e3a57806001019250616d7d565b898661ffff168260010181616e4b57fe5b0661ffff8110616e5757fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b602084015273ffffffffffffffffffffffffffffffffffffffff6b0100000000000000000000008204169183019190915260ff7f010000000000000000000000000000000000000000000000000000000000000090910416151560608201528551909450600090616ef3908b908b616c7c565b9050808015616f0c5750616f0c8a8a8760000151616c7c565b15616f175750616f34565b80616f2757600182039250616f2e565b8160010193505b50616d7d565b5050509550959350505050565b60028a810b900b600090815260208c90526040812080546fffffffffffffffffffffffffffffffff1682616f75828d614a2d565b9050846fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561700a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4c4f000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6fffffffffffffffffffffffffffffffff828116159082161581141594501561715a578c60020b8e60020b1361710e57600183018b9055600283018a90556003830180547fffffffffff0000000000000000000000000000000000000000ffffffffffffff1667010000000000000073ffffffffffffffffffffffffffffffffffffffff8c1602177fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000001666ffffffffffffff60068b900b16177fff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff167b0100000000000000000000000000000000000000000000000000000063ffffffff8a16021790555b6003830180547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790555b82547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff8216178355856171d15782546171cc906171c7907001000000000000000000000000000000009004600f90810b810b908f900b614643565b6156a8565b6171ff565b82546171ff906171c7907001000000000000000000000000000000009004600f90810b810b908f900b614627565b8354600f9190910b6fffffffffffffffffffffffffffffffff9081167001000000000000000000000000000000000291161790925550909c9b505050505050505050505050565b8060020b8260020b8161725557fe5b0760020b1561726357600080fd5b60008061727e8360020b8560020b8161727857fe5b05615e92565b600191820b820b60009081526020979097526040909620805460ff9097169190911b90951890945550505050565b600285810b80820b60009081526020899052604080822088850b850b83529082209193849391929184918291908a900b126172f257505060018201546002830154617305565b8360010154880391508360020154870390505b6000808b60020b8b60020b12156173275750506001830154600284015461733a565b84600101548a0391508460020154890390505b92909803979097039b96909503949094039850939650505050505050565b6040805160a08101825285546fffffffffffffffffffffffffffffffff90811682526001870154602083015260028701549282019290925260038601548083166060830152700100000000000000000000000000000000900490911660808201526000600f85900b61744b5781516fffffffffffffffffffffffffffffffff1661744357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f4e50000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b50805161745a565b81516174579086614a2d565b90505b60006174948360200151860384600001516fffffffffffffffffffffffffffffffff16700100000000000000000000000000000000614659565b905060006174d08460400151860385600001516fffffffffffffffffffffffffffffffff16700100000000000000000000000000000000614659565b905086600f0b6000146175185787547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff84161788555b60018801869055600288018590556fffffffffffffffffffffffffffffffff821615158061755857506000816fffffffffffffffffffffffffffffffff16115b156175c4576003880180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821685018216178082167001000000000000000000000000000000009182900483168501909216021790555b5050505050505050565b600290810b810b6000908152602092909252604082208281556001810183905590810182905560030155565b8073ffffffffffffffffffffffffffffffffffffffff81168114613e7157600080fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b6040805160808101825260008082526020820181905291810182905260608101919091529056fea2646970667358221220c186b9a0089f20a2f3c54ff0d2f772daf3a8b3a2ab747f3ca54c05872070e7f164736f6c63430007060033"; type UniswapV3PoolConstructorParams = | [signer?: Signer] diff --git a/packages/protocol/contracts/external/chainlink/IAggregatorV3.sol b/packages/protocol/contracts/external/chainlink/IAggregatorV3.sol index b5e774f0..ce704699 100644 --- a/packages/protocol/contracts/external/chainlink/IAggregatorV3.sol +++ b/packages/protocol/contracts/external/chainlink/IAggregatorV3.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.4; /// @title IAggregatorV3 /// @author Hifi /// @dev Forked from Chainlink -/// github.com/smartcontractkit/chainlink/blob/v1.2.0/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol +/// https://github.com/smartcontractkit/chainlink/blob/v1.2.0/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol interface IAggregatorV3 { function decimals() external view returns (uint8); diff --git a/packages/protocol/contracts/external/uniswap/interfaces/IUniswapV3Pool.sol b/packages/protocol/contracts/external/uniswap/interfaces/IUniswapV3Pool.sol new file mode 100644 index 00000000..98f226d6 --- /dev/null +++ b/packages/protocol/contracts/external/uniswap/interfaces/IUniswapV3Pool.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity >=0.8.4; + +/// @title IUniswapV3Pool +/// @author Hifi +/// @dev Forked from Uniswap +/// https://github.com/Uniswap/v3-core/blob/v1.0.0/contracts/interfaces/IUniswapV3Factory.sol +interface IUniswapV3Pool { + function factory() external view returns (address); + + function fee() external view returns (uint24); + + function initialize(uint160 sqrtPriceX96) external; + + function maxLiquidityPerTick() external view returns (uint128); + + function observe(uint32[] calldata secondsAgos) + external + view + returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); + + function observations(uint256 index) + external + view + returns ( + uint32 blockTimestamp, + int56 tickCumulative, + uint160 secondsPerLiquidityCumulativeX128, + bool initialized + ); + + function slot0() + external + view + returns ( + uint160 sqrtPriceX96, + int24 tick, + uint16 observationIndex, + uint16 observationCardinality, + uint16 observationCardinalityNext, + uint8 feeProtocol, + bool unlocked + ); + + function tickSpacing() external view returns (int24); + + function token0() external view returns (address); + + function token1() external view returns (address); +} diff --git a/packages/protocol/contracts/external/uniswap/libraries/FullMath.sol b/packages/protocol/contracts/external/uniswap/libraries/FullMath.sol new file mode 100644 index 00000000..7dec6fc2 --- /dev/null +++ b/packages/protocol/contracts/external/uniswap/libraries/FullMath.sol @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: MIT +// solhint-disable max-line-length, no-inline-assembly, reason-string +pragma solidity ^0.8.4; + +/// @title FullMath +/// @author Hifi +/// @dev Forked from Euler +/// https://github.com/euler-xyz/euler-contracts/blob/dfaa7788b17ac7c2a826a3ed242d7181998a778f/contracts/vendor/FullMath.sol +library FullMath { + /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 + /// @param a The multiplicand + /// @param b The multiplier + /// @param denominator The divisor + /// @return result The 256-bit result + /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv + function mulDiv( + uint256 a, + uint256 b, + uint256 denominator + ) internal pure returns (uint256 result) { + unchecked { + // 512-bit multiply [prod1 prod0] = a * b + // Compute the product mod 2**256 and mod 2**256 - 1 + // then use the Chinese Remainder Theorem to reconstruct + // the 512 bit result. The result is stored in two 256 + // variables such that product = prod1 * 2**256 + prod0 + uint256 prod0; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly { + let mm := mulmod(a, b, not(0)) + prod0 := mul(a, b) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division + if (prod1 == 0) { + require(denominator > 0); + assembly { + result := div(prod0, denominator) + } + return result; + } + + // Make sure the result is less than 2**256. + // Also prevents denominator == 0 + require(denominator > prod1); + + /////////////////////////////////////////////// + // 512 by 256 division. + /////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0] + // Compute remainder using mulmod + uint256 remainder; + assembly { + remainder := mulmod(a, b, denominator) + } + // Subtract 256 bit number from 512 bit number + assembly { + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + // Factor powers of two out of denominator + // Compute largest power of two divisor of denominator. + // Always >= 1. + uint256 twos = denominator & (~denominator + 1); + + // Divide denominator by power of two + assembly { + denominator := div(denominator, twos) + } + + // Divide [prod1 prod0] by the factors of two + assembly { + prod0 := div(prod0, twos) + } + // Shift in bits from prod1 into prod0. For this we need + // to flip `twos` such that it is 2**256 / twos. + // If twos is zero, then it becomes one + assembly { + twos := add(div(sub(0, twos), twos), 1) + } + prod0 |= prod1 * twos; + + // Invert denominator mod 2**256 + // Now that denominator is an odd number, it has an inverse + // modulo 2**256 such that denominator * inv = 1 mod 2**256. + // Compute the inverse by starting with a seed that is correct + // correct for four bits. That is, denominator * inv = 1 mod 2**4 + uint256 inv = (3 * denominator) ^ 2; + // Now use Newton-Raphson iteration to improve the precision. + // Thanks to Hensel's lifting lemma, this also works in modular + // arithmetic, doubling the correct bits in each step. + inv *= 2 - denominator * inv; // inverse mod 2**8 + inv *= 2 - denominator * inv; // inverse mod 2**16 + inv *= 2 - denominator * inv; // inverse mod 2**32 + inv *= 2 - denominator * inv; // inverse mod 2**64 + inv *= 2 - denominator * inv; // inverse mod 2**128 + inv *= 2 - denominator * inv; // inverse mod 2**256 + + // Because the division is now exact we can divide by multiplying + // with the modular inverse of denominator. This will give us the + // correct result modulo 2**256. Since the precoditions guarantee + // that the outcome is less than 2**256, this is the final result. + // We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inv; + return result; + } + } + + /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 + /// @param a The multiplicand + /// @param b The multiplier + /// @param denominator The divisor + /// @return result The 256-bit result + function mulDivRoundingUp( + uint256 a, + uint256 b, + uint256 denominator + ) internal pure returns (uint256 result) { + unchecked { + result = mulDiv(a, b, denominator); + if (mulmod(a, b, denominator) > 0) { + require(result < type(uint256).max); + result++; + } + } + } +} diff --git a/packages/protocol/contracts/external/uniswap/libraries/TickMath.sol b/packages/protocol/contracts/external/uniswap/libraries/TickMath.sol new file mode 100644 index 00000000..c1db5d43 --- /dev/null +++ b/packages/protocol/contracts/external/uniswap/libraries/TickMath.sol @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// solhint-disable code-complexity, max-line-length, no-inline-assembly, var-name-mixedcase +pragma solidity ^0.8.4; + +/// @title TickMath +/// @author Hifi +/// @dev Forked from Euler +/// https://github.com/euler-xyz/euler-contracts/blob/dfaa7788b17ac7c2a826a3ed242d7181998a778f/contracts/vendor/TickMath.sol +library TickMath { + /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 + int24 internal constant MIN_TICK = -887272; + /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 + int24 internal constant MAX_TICK = -MIN_TICK; + + /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) + uint160 internal constant MIN_SQRT_RATIO = 4295128739; + /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) + uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; + + /// @notice Calculates sqrt(1.0001^tick) * 2^96 + /// @dev Throws if |tick| > max tick + /// @param tick The input tick for the above formula + /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) + /// at the given tick + function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) { + unchecked { + uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick)); + require(absTick <= uint256(int256(MAX_TICK)), "T"); + + uint256 ratio = absTick & 0x1 != 0 + ? 0xfffcb933bd6fad37aa2d162d1a594001 + : 0x100000000000000000000000000000000; + if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; + if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; + if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; + if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; + if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; + if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; + if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; + if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; + if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; + if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; + if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; + if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; + if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; + if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; + if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; + if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; + if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; + if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; + if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; + + if (tick > 0) ratio = type(uint256).max / ratio; + + // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. + // we then downcast because we know the result always fits within 160 bits due to our tick input constraint + // we round up in the division so getTickAtSqrtRatio of the output price is always consistent + sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); + } + } + + /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio + /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may + /// ever return. + /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 + /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio + function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { + unchecked { + // second inequality must be < because the price can never reach the price at the max tick + require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, "R"); + uint256 ratio = uint256(sqrtPriceX96) << 32; + + uint256 r = ratio; + uint256 msb = 0; + + assembly { + let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := shl(5, gt(r, 0xFFFFFFFF)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := shl(4, gt(r, 0xFFFF)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := shl(3, gt(r, 0xFF)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := shl(2, gt(r, 0xF)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := shl(1, gt(r, 0x3)) + msb := or(msb, f) + r := shr(f, r) + } + assembly { + let f := gt(r, 0x1) + msb := or(msb, f) + } + + if (msb >= 128) r = ratio >> (msb - 127); + else r = ratio << (127 - msb); + + int256 log_2 = (int256(msb) - 128) << 64; + + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(63, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(62, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(61, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(60, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(59, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(58, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(57, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(56, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(55, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(54, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(53, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(52, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(51, f)) + r := shr(f, r) + } + assembly { + r := shr(127, mul(r, r)) + let f := shr(128, r) + log_2 := or(log_2, shl(50, f)) + } + + int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number + + int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); + int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); + + tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; + } + } +} diff --git a/packages/protocol/contracts/oracles/IUniswapV3PriceFeed.sol b/packages/protocol/contracts/oracles/IUniswapV3PriceFeed.sol new file mode 100644 index 00000000..d1e5c9f3 --- /dev/null +++ b/packages/protocol/contracts/oracles/IUniswapV3PriceFeed.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.8.4; + +import "@prb/contracts/token/erc20/IErc20.sol"; +import "../external/chainlink/IAggregatorV3.sol"; +import "../external/uniswap/interfaces/IUniswapV3Pool.sol"; + +/// @title IUniswapV3PriceFeed +/// @author Hifi +/// @notice Chainlink-compatible price feed for Uniswap V3 pools. +interface IUniswapV3PriceFeed is IAggregatorV3 { + /// CUSTOM ERRORS /// + + /// @notice Emitted when the quote asset is not in the pool. + error IUniswapV3PriceFeed__QuoteAssetNotInPool(IErc20 quoteAsset); + + /// @notice Emitted when the TWAP criteria is not satisfied. + error IUniswapV3PriceFeed__TwapCriteriaNotSatisfied(); + + /// @notice Emitted when the max price is less than or equal to zero. + error IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero(); + + /// CONSTANT FUNCTIONS /// + + /// @notice The base asset for price calculations. + function baseAsset() external view returns (IErc20); + + /// @notice The upper price band for the price feed. + function maxPrice() external view returns (int256); + + /// @notice The Uniswap V3 pool. + function pool() external view returns (IUniswapV3Pool); + + /// @notice The quote asset for price calculations. + function quoteAsset() external view returns (IErc20); + + /// @notice The time window for the TWAP calculation. + function twapInterval() external view returns (uint32); + + /// NON-CONSTANT FUNCTIONS /// + + /// @notice Updates the max price. + /// + /// Requirements: + /// + /// - The caller must be the owner. + /// - The new max price must be greater than zero. + /// + /// @param maxPrice_ The new max price. + function setMaxPrice(int256 maxPrice_) external; +} diff --git a/packages/protocol/contracts/oracles/UniswapV3PriceFeed.sol b/packages/protocol/contracts/oracles/UniswapV3PriceFeed.sol new file mode 100644 index 00000000..199fa040 --- /dev/null +++ b/packages/protocol/contracts/oracles/UniswapV3PriceFeed.sol @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.4; + +import "@prb/contracts/access/Ownable.sol"; +import "@prb/contracts/token/erc20/IErc20.sol"; + +import "./IUniswapV3PriceFeed.sol"; +import "../external/chainlink/IAggregatorV3.sol"; +import "../external/uniswap/interfaces/IUniswapV3Pool.sol"; +import "../external/uniswap/libraries/TickMath.sol"; +import "../external/uniswap/libraries/FullMath.sol"; + +/// @title UniswapV3PriceFeed +/// @author Hifi +/// @dev Although the contract is production-ready, it has not been audited for security vulnerabilities. Use at your own risk. +contract UniswapV3PriceFeed is + Ownable, // one dependency + IUniswapV3PriceFeed // one dependency +{ + /// PUBLIC STORAGE /// + + /// @inheritdoc IUniswapV3PriceFeed + IErc20 public immutable override baseAsset; + + /// @inheritdoc IUniswapV3PriceFeed + int256 public override maxPrice; + + /// @inheritdoc IUniswapV3PriceFeed + IUniswapV3Pool public immutable override pool; + + /// @inheritdoc IUniswapV3PriceFeed + IErc20 public immutable override quoteAsset; + + /// @inheritdoc IUniswapV3PriceFeed + uint32 public immutable override twapInterval; + + /// INTERNAL STORAGE /// + + /// @dev The Uniswap V3 pool's token0. + IErc20 internal immutable token0; + + /// @dev The ERC20 decimals of "token0". + uint8 internal immutable token0Decimals; + + /// @dev The Uniswap V3 pool's token1. + IErc20 internal immutable token1; + + /// @dev The ERC20 decimals of "token1". + uint8 internal immutable token1Decimals; + + /// CONSTRUCTOR /// + + /// @notice Instantiates the UniswapV3PriceFeed contract. + /// @param pool_ The address of the Uniswap V3 pool. + /// @param quoteAsset_ The address of the quote asset for price calculation. + /// @param twapInterval_ The time window for the TWAP calculation. + /// @param maxPrice_ The maximum price for the price feed. + constructor( + IUniswapV3Pool pool_, + IErc20 quoteAsset_, + uint32 twapInterval_, + int256 maxPrice_ + ) { + quoteAsset = quoteAsset_; + + token0 = IErc20(pool_.token0()); + token1 = IErc20(pool_.token1()); + + // Ensure the quote asset is in the provided pool + if (quoteAsset != token0 && quoteAsset != token1) { + revert IUniswapV3PriceFeed__QuoteAssetNotInPool(quoteAsset); + } + + baseAsset = quoteAsset == token1 ? token0 : token1; + pool = pool_; + + // Fetch the pool cardinality and most recent observation index. + (, , uint16 index, uint16 cardinality, uint16 cardinalityNext, , ) = pool.slot0(); + + // Ensure the oldest pool observation is initialized and satisfies the TWAP interval. + // The next observation at index + 1 is the oldest observation in the ring buffer. + (uint32 oldestAvailableAge, , , bool initialized) = pool.observations((index + 1) % cardinality); + + // If the next observation is not initialized, all observations of higher indices are also not initialized. + // Therefore, revert to index 0 to find the oldest initialized observation. + if (!initialized) (oldestAvailableAge, , , ) = pool.observations(0); + + // Calculate the available TWAP interval. + uint256 availableTwapInterval = block.timestamp - oldestAvailableAge; + + // Calculate the minimum cardinality, assuming 12.5 second block times. + uint16 minimumCardinality = uint16((twapInterval_ * 10) / 125); + + // Ensure the available TWAP interval and cardinality satisfy the TWAP criteria. + if (availableTwapInterval < twapInterval_ || cardinalityNext < minimumCardinality) { + revert IUniswapV3PriceFeed__TwapCriteriaNotSatisfied(); + } + + // Ensure the max price is not less than or equal to zero. + if (maxPrice_ <= 0) revert IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero(); + + token0Decimals = token0.decimals(); + token1Decimals = token1.decimals(); + twapInterval = twapInterval_; + maxPrice = maxPrice_; + } + + /// PUBLIC CONSTANT FUNCTIONS /// + + /// @inheritdoc IAggregatorV3 + function decimals() external pure override returns (uint8) { + return 8; + } + + /// @inheritdoc IAggregatorV3 + function description() external view override returns (string memory) { + return string.concat(baseAsset.symbol(), " / ", quoteAsset.symbol()); + } + + /// @inheritdoc IAggregatorV3 + function version() external pure override returns (uint256) { + return 1; + } + + /// @inheritdoc IAggregatorV3 + function getRoundData(uint80 roundId_) + external + view + override + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + return (roundId_, getPriceInternal(), 0, 0, 0); + } + + /// @inheritdoc IAggregatorV3 + function latestRoundData() + external + view + override + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + return (0, getPriceInternal(), 0, block.timestamp, 0); + } + + /// PUBLIC NON-CONSTANT FUNCTIONS /// + + /// @inheritdoc IUniswapV3PriceFeed + function setMaxPrice(int256 maxPrice_) external override onlyOwner { + if (maxPrice_ <= 0) revert IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero(); + maxPrice = maxPrice_; + } + + /// INTERNAL CONSTANT FUNCTIONS /// + + /// @dev Returns Chainlink-compatible price data from the Uniswap V3 pool. If the quote asset is token1, + /// the formula used is: + /// + /// sqrtPriceX96^2 + /// price = ---------------- + /// Q192 + /// + /// Otherwise, the formula is: + /// + /// Q192 + /// price = ---------------- + /// sqrtPriceX96^2 + /// + /// @dev See OracleLibrary.sol in the Uniswap V3 periphery for more details: + /// https://github.com/Uniswap/v3-periphery/blob/v1.3.0/contracts/libraries/OracleLibrary.sol + /// + /// @return price The Chainlink-compatible price of the other asset in terms of the quote asset. + function getPriceInternal() internal view returns (int256 price) { + uint32[] memory secondsAgo = new uint32[](2); + secondsAgo[0] = twapInterval; + secondsAgo[1] = 0; + + (int56[] memory tickCumulatives, ) = pool.observe(secondsAgo); + int24 tick = int24((tickCumulatives[1] - tickCumulatives[0]) / int32(twapInterval)); + uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(tick); + + if (quoteAsset == token1) { + // Calculate the Chainlink-compatible price of token0 in terms of token1 + price = int256( + FullMath.mulDiv(sqrtPriceX96, sqrtPriceX96, (1 << 192) / 10**(8 + token0Decimals)) / 10**token1Decimals + ); + } else { + // Calculate the Chainlink-compatible price of token1 in terms of token0 + price = int256(FullMath.mulDiv(sqrtPriceX96, sqrtPriceX96, (1 << 192) / 10**(8 + token0Decimals))); + if (price == 0) return int256(10**(16 + token1Decimals)); + price = int256(10**(16 + token1Decimals)) / price; + } + if (price > maxPrice) return maxPrice; + if (price == 0) return 1; + } +} diff --git a/packages/protocol/contracts/test/GodModeUniswapV3PriceFeed.sol b/packages/protocol/contracts/test/GodModeUniswapV3PriceFeed.sol new file mode 100644 index 00000000..0ec4f4c8 --- /dev/null +++ b/packages/protocol/contracts/test/GodModeUniswapV3PriceFeed.sol @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: UNLICENSED +// solhint-disable +pragma solidity ^0.8.4; + +import "@prb/contracts/token/erc20/IErc20.sol"; + +import "../external/uniswap/interfaces/IUniswapV3Pool.sol"; +import "../oracles/IUniswapV3PriceFeed.sol"; +import "../oracles/UniswapV3PriceFeed.sol"; + +/// @title GodModeUniswapV3PriceFeed +/// @author Hifi +/// @dev Strictly for test purposes. Do not use in production. +contract GodModeUniswapV3PriceFeed is IUniswapV3PriceFeed { + IUniswapV3PriceFeed internal instance; + + constructor( + IUniswapV3Pool pool_, + IErc20 quoteAsset_, + uint32 twapInterval_ + ) { + instance = new UniswapV3PriceFeed(pool_, quoteAsset_, twapInterval_, type(int256).max); + } + + function baseAsset() external view returns (IErc20) { + return instance.baseAsset(); + } + + function decimals() external view returns (uint8) { + return instance.decimals(); + } + + function description() external view returns (string memory) { + return instance.description(); + } + + function maxPrice() external view returns (int256) { + return instance.maxPrice(); + } + + function version() external view returns (uint256) { + return instance.version(); + } + + function getRoundData(uint80 _roundId) + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + return instance.getRoundData(_roundId); + } + + function latestRoundData() + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + return instance.latestRoundData(); + } + + function pool() external view returns (IUniswapV3Pool) { + return instance.pool(); + } + + function quoteAsset() external view returns (IErc20) { + return instance.quoteAsset(); + } + + function setMaxPrice(int256 maxPrice_) external { + instance.setMaxPrice(maxPrice_); + } + + function twapInterval() external view returns (uint32) { + return instance.twapInterval(); + } + + // solhint-disable-next-line no-complex-fallback + fallback() external payable { + (bool success, ) = address(instance).call{ value: msg.value }(msg.data); + assert(success); + } + + receive() external payable { + (bool success, ) = address(instance).call{ value: msg.value }(""); + assert(success); + } + + function __godMode_setMaxPrice(int256 newMaxPrice) external { + instance = new UniswapV3PriceFeed(instance.pool(), instance.quoteAsset(), instance.twapInterval(), newMaxPrice); + } + + function __godMode_setPool(IUniswapV3Pool newPool) external { + instance = new UniswapV3PriceFeed(newPool, instance.quoteAsset(), instance.twapInterval(), instance.maxPrice()); + } + + function __godMode_setQuoteAsset(IErc20 newQuoteAsset) external { + instance = new UniswapV3PriceFeed(instance.pool(), newQuoteAsset, instance.twapInterval(), instance.maxPrice()); + } + + function __godMode_setTwapInterval(uint32 newTwapInterval) external { + instance = new UniswapV3PriceFeed(instance.pool(), instance.quoteAsset(), newTwapInterval, instance.maxPrice()); + } +} diff --git a/packages/protocol/hardhat.config.ts b/packages/protocol/hardhat.config.ts index fc2cc7bb..4d169d5b 100644 --- a/packages/protocol/hardhat.config.ts +++ b/packages/protocol/hardhat.config.ts @@ -90,14 +90,36 @@ const config: HardhatUserConfig = { tests: "./test", }, solidity: { - version: "0.8.12", - settings: { - metadata: { - bytecodeHash: "none", + compilers: [ + { + version: "0.8.12", + settings: { + metadata: { + bytecodeHash: "none", + }, + optimizer: { + enabled: true, + runs: 800, + }, + }, }, - optimizer: { - enabled: true, - runs: 800, + ], + overrides: { + "contracts/oracles/UniswapV3PriceFeed.sol": { + version: "0.8.12", + settings: { + metadata: { + bytecodeHash: "none", + }, + optimizer: { + enabled: true, + runs: 1_000_000, + details: { + yul: true, + }, + }, + viaIR: true, + }, }, }, }, diff --git a/packages/protocol/package.json b/packages/protocol/package.json index 6c59547c..9cdc39d8 100644 --- a/packages/protocol/package.json +++ b/packages/protocol/package.json @@ -38,6 +38,7 @@ "@types/node": "^17.0.23", "@typescript-eslint/eslint-plugin": "^5.17.0", "@typescript-eslint/parser": "^5.17.0", + "@uniswap/v3-sdk": "^3.9.0", "chai": "^4.3.6", "cross-env": "^7.0.3", "dotenv": "^16.0.0", diff --git a/packages/protocol/src/types/contracts/external/common/index.ts b/packages/protocol/src/types/contracts/external/common/index.ts new file mode 100644 index 00000000..8312ccd9 --- /dev/null +++ b/packages/protocol/src/types/contracts/external/common/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { IERC20 } from "./IERC20"; diff --git a/packages/protocol/src/types/contracts/external/index.ts b/packages/protocol/src/types/contracts/external/index.ts index d93a18ae..331b0d2e 100644 --- a/packages/protocol/src/types/contracts/external/index.ts +++ b/packages/protocol/src/types/contracts/external/index.ts @@ -4,5 +4,8 @@ /* eslint-disable */ import type * as chainlink from "./chainlink"; +import type * as uniswap from "./uniswap"; export type { chainlink }; + +export type { uniswap }; diff --git a/packages/protocol/src/types/contracts/external/uniswap/index.ts b/packages/protocol/src/types/contracts/external/uniswap/index.ts new file mode 100644 index 00000000..550f4a5d --- /dev/null +++ b/packages/protocol/src/types/contracts/external/uniswap/index.ts @@ -0,0 +1,8 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type * as interfaces from "./interfaces"; + +export type { interfaces }; diff --git a/packages/protocol/src/types/contracts/external/uniswap/interfaces/IUniswapV3Pool.ts b/packages/protocol/src/types/contracts/external/uniswap/interfaces/IUniswapV3Pool.ts new file mode 100644 index 00000000..cb291526 --- /dev/null +++ b/packages/protocol/src/types/contracts/external/uniswap/interfaces/IUniswapV3Pool.ts @@ -0,0 +1,358 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from "../../../../common"; +import type { FunctionFragment, Result } from "@ethersproject/abi"; +import type { Listener, Provider } from "@ethersproject/providers"; +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; + +export interface IUniswapV3PoolInterface extends utils.Interface { + functions: { + "factory()": FunctionFragment; + "fee()": FunctionFragment; + "initialize(uint160)": FunctionFragment; + "maxLiquidityPerTick()": FunctionFragment; + "observations(uint256)": FunctionFragment; + "observe(uint32[])": FunctionFragment; + "slot0()": FunctionFragment; + "tickSpacing()": FunctionFragment; + "token0()": FunctionFragment; + "token1()": FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | "factory" + | "fee" + | "initialize" + | "maxLiquidityPerTick" + | "observations" + | "observe" + | "slot0" + | "tickSpacing" + | "token0" + | "token1" + ): FunctionFragment; + + encodeFunctionData(functionFragment: "factory", values?: undefined): string; + encodeFunctionData(functionFragment: "fee", values?: undefined): string; + encodeFunctionData( + functionFragment: "initialize", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "maxLiquidityPerTick", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "observations", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "observe", + values: [BigNumberish[]] + ): string; + encodeFunctionData(functionFragment: "slot0", values?: undefined): string; + encodeFunctionData( + functionFragment: "tickSpacing", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "token0", values?: undefined): string; + encodeFunctionData(functionFragment: "token1", values?: undefined): string; + + decodeFunctionResult(functionFragment: "factory", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "fee", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "initialize", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "maxLiquidityPerTick", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "observations", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "observe", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "slot0", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "tickSpacing", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "token0", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "token1", data: BytesLike): Result; + + events: {}; +} + +export interface IUniswapV3Pool extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: IUniswapV3PoolInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + factory(overrides?: CallOverrides): Promise<[string]>; + + fee(overrides?: CallOverrides): Promise<[number]>; + + initialize( + sqrtPriceX96: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise<[BigNumber]>; + + observations( + index: BigNumberish, + overrides?: CallOverrides + ): Promise< + [number, BigNumber, BigNumber, boolean] & { + blockTimestamp: number; + tickCumulative: BigNumber; + secondsPerLiquidityCumulativeX128: BigNumber; + initialized: boolean; + } + >; + + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise< + [BigNumber[], BigNumber[]] & { + tickCumulatives: BigNumber[]; + secondsPerLiquidityCumulativeX128s: BigNumber[]; + } + >; + + slot0( + overrides?: CallOverrides + ): Promise< + [BigNumber, number, number, number, number, number, boolean] & { + sqrtPriceX96: BigNumber; + tick: number; + observationIndex: number; + observationCardinality: number; + observationCardinalityNext: number; + feeProtocol: number; + unlocked: boolean; + } + >; + + tickSpacing(overrides?: CallOverrides): Promise<[number]>; + + token0(overrides?: CallOverrides): Promise<[string]>; + + token1(overrides?: CallOverrides): Promise<[string]>; + }; + + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + initialize( + sqrtPriceX96: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise; + + observations( + index: BigNumberish, + overrides?: CallOverrides + ): Promise< + [number, BigNumber, BigNumber, boolean] & { + blockTimestamp: number; + tickCumulative: BigNumber; + secondsPerLiquidityCumulativeX128: BigNumber; + initialized: boolean; + } + >; + + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise< + [BigNumber[], BigNumber[]] & { + tickCumulatives: BigNumber[]; + secondsPerLiquidityCumulativeX128s: BigNumber[]; + } + >; + + slot0( + overrides?: CallOverrides + ): Promise< + [BigNumber, number, number, number, number, number, boolean] & { + sqrtPriceX96: BigNumber; + tick: number; + observationIndex: number; + observationCardinality: number; + observationCardinalityNext: number; + feeProtocol: number; + unlocked: boolean; + } + >; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + + callStatic: { + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + initialize( + sqrtPriceX96: BigNumberish, + overrides?: CallOverrides + ): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise; + + observations( + index: BigNumberish, + overrides?: CallOverrides + ): Promise< + [number, BigNumber, BigNumber, boolean] & { + blockTimestamp: number; + tickCumulative: BigNumber; + secondsPerLiquidityCumulativeX128: BigNumber; + initialized: boolean; + } + >; + + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise< + [BigNumber[], BigNumber[]] & { + tickCumulatives: BigNumber[]; + secondsPerLiquidityCumulativeX128s: BigNumber[]; + } + >; + + slot0( + overrides?: CallOverrides + ): Promise< + [BigNumber, number, number, number, number, number, boolean] & { + sqrtPriceX96: BigNumber; + tick: number; + observationIndex: number; + observationCardinality: number; + observationCardinalityNext: number; + feeProtocol: number; + unlocked: boolean; + } + >; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + }; + + filters: {}; + + estimateGas: { + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + initialize( + sqrtPriceX96: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise; + + observations( + index: BigNumberish, + overrides?: CallOverrides + ): Promise; + + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise; + + slot0(overrides?: CallOverrides): Promise; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + initialize( + sqrtPriceX96: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + maxLiquidityPerTick( + overrides?: CallOverrides + ): Promise; + + observations( + index: BigNumberish, + overrides?: CallOverrides + ): Promise; + + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise; + + slot0(overrides?: CallOverrides): Promise; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + }; +} diff --git a/packages/protocol/src/types/contracts/external/uniswap/interfaces/index.ts b/packages/protocol/src/types/contracts/external/uniswap/interfaces/index.ts new file mode 100644 index 00000000..454c1126 --- /dev/null +++ b/packages/protocol/src/types/contracts/external/uniswap/interfaces/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { IUniswapV3Pool } from "./IUniswapV3Pool"; diff --git a/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState.ts b/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState.ts new file mode 100644 index 00000000..271c19cb --- /dev/null +++ b/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState.ts @@ -0,0 +1,176 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from "../../../../../common"; +import type { FunctionFragment, Result } from "@ethersproject/abi"; +import type { Listener, Provider } from "@ethersproject/providers"; +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; + +export interface IUniswapV3PoolDerivedStateInterface extends utils.Interface { + functions: { + "observe(uint32[])": FunctionFragment; + "snapshotCumulativesInside(int24,int24)": FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: "observe" | "snapshotCumulativesInside" + ): FunctionFragment; + + encodeFunctionData( + functionFragment: "observe", + values: [BigNumberish[]] + ): string; + encodeFunctionData( + functionFragment: "snapshotCumulativesInside", + values: [BigNumberish, BigNumberish] + ): string; + + decodeFunctionResult(functionFragment: "observe", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "snapshotCumulativesInside", + data: BytesLike + ): Result; + + events: {}; +} + +export interface IUniswapV3PoolDerivedState extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: IUniswapV3PoolDerivedStateInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise< + [BigNumber[], BigNumber[]] & { + tickCumulatives: BigNumber[]; + secondsPerLiquidityCumulativeX128s: BigNumber[]; + } + >; + + snapshotCumulativesInside( + tickLower: BigNumberish, + tickUpper: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, number] & { + tickCumulativeInside: BigNumber; + secondsPerLiquidityInsideX128: BigNumber; + secondsInside: number; + } + >; + }; + + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise< + [BigNumber[], BigNumber[]] & { + tickCumulatives: BigNumber[]; + secondsPerLiquidityCumulativeX128s: BigNumber[]; + } + >; + + snapshotCumulativesInside( + tickLower: BigNumberish, + tickUpper: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, number] & { + tickCumulativeInside: BigNumber; + secondsPerLiquidityInsideX128: BigNumber; + secondsInside: number; + } + >; + + callStatic: { + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise< + [BigNumber[], BigNumber[]] & { + tickCumulatives: BigNumber[]; + secondsPerLiquidityCumulativeX128s: BigNumber[]; + } + >; + + snapshotCumulativesInside( + tickLower: BigNumberish, + tickUpper: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, number] & { + tickCumulativeInside: BigNumber; + secondsPerLiquidityInsideX128: BigNumber; + secondsInside: number; + } + >; + }; + + filters: {}; + + estimateGas: { + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise; + + snapshotCumulativesInside( + tickLower: BigNumberish, + tickUpper: BigNumberish, + overrides?: CallOverrides + ): Promise; + }; + + populateTransaction: { + observe( + secondsAgos: BigNumberish[], + overrides?: CallOverrides + ): Promise; + + snapshotCumulativesInside( + tickLower: BigNumberish, + tickUpper: BigNumberish, + overrides?: CallOverrides + ): Promise; + }; +} diff --git a/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables.ts b/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables.ts new file mode 100644 index 00000000..4855a08f --- /dev/null +++ b/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables.ts @@ -0,0 +1,170 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from "../../../../../common"; +import type { FunctionFragment, Result } from "@ethersproject/abi"; +import type { Listener, Provider } from "@ethersproject/providers"; +import type { + BaseContract, + BigNumber, + BytesLike, + CallOverrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; + +export interface IUniswapV3PoolImmutablesInterface extends utils.Interface { + functions: { + "factory()": FunctionFragment; + "fee()": FunctionFragment; + "maxLiquidityPerTick()": FunctionFragment; + "tickSpacing()": FunctionFragment; + "token0()": FunctionFragment; + "token1()": FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | "factory" + | "fee" + | "maxLiquidityPerTick" + | "tickSpacing" + | "token0" + | "token1" + ): FunctionFragment; + + encodeFunctionData(functionFragment: "factory", values?: undefined): string; + encodeFunctionData(functionFragment: "fee", values?: undefined): string; + encodeFunctionData( + functionFragment: "maxLiquidityPerTick", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "tickSpacing", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "token0", values?: undefined): string; + encodeFunctionData(functionFragment: "token1", values?: undefined): string; + + decodeFunctionResult(functionFragment: "factory", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "fee", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "maxLiquidityPerTick", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "tickSpacing", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "token0", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "token1", data: BytesLike): Result; + + events: {}; +} + +export interface IUniswapV3PoolImmutables extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: IUniswapV3PoolImmutablesInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + factory(overrides?: CallOverrides): Promise<[string]>; + + fee(overrides?: CallOverrides): Promise<[number]>; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise<[BigNumber]>; + + tickSpacing(overrides?: CallOverrides): Promise<[number]>; + + token0(overrides?: CallOverrides): Promise<[string]>; + + token1(overrides?: CallOverrides): Promise<[string]>; + }; + + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + + callStatic: { + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + }; + + filters: {}; + + estimateGas: { + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + maxLiquidityPerTick(overrides?: CallOverrides): Promise; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + factory(overrides?: CallOverrides): Promise; + + fee(overrides?: CallOverrides): Promise; + + maxLiquidityPerTick( + overrides?: CallOverrides + ): Promise; + + tickSpacing(overrides?: CallOverrides): Promise; + + token0(overrides?: CallOverrides): Promise; + + token1(overrides?: CallOverrides): Promise; + }; +} diff --git a/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/index.ts b/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/index.ts new file mode 100644 index 00000000..91d6e70e --- /dev/null +++ b/packages/protocol/src/types/contracts/external/uniswap/interfaces/pool/index.ts @@ -0,0 +1,5 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { IUniswapV3PoolDerivedState } from "./IUniswapV3PoolDerivedState"; +export type { IUniswapV3PoolImmutables } from "./IUniswapV3PoolImmutables"; diff --git a/packages/protocol/src/types/contracts/oracles/IUniswapV3PriceFeed.ts b/packages/protocol/src/types/contracts/oracles/IUniswapV3PriceFeed.ts new file mode 100644 index 00000000..a7776d79 --- /dev/null +++ b/packages/protocol/src/types/contracts/oracles/IUniswapV3PriceFeed.ts @@ -0,0 +1,346 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from "../../common"; +import type { FunctionFragment, Result } from "@ethersproject/abi"; +import type { Listener, Provider } from "@ethersproject/providers"; +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; + +export interface IUniswapV3PriceFeedInterface extends utils.Interface { + functions: { + "baseAsset()": FunctionFragment; + "decimals()": FunctionFragment; + "description()": FunctionFragment; + "getRoundData(uint80)": FunctionFragment; + "latestRoundData()": FunctionFragment; + "maxPrice()": FunctionFragment; + "pool()": FunctionFragment; + "quoteAsset()": FunctionFragment; + "setMaxPrice(int256)": FunctionFragment; + "twapInterval()": FunctionFragment; + "version()": FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | "baseAsset" + | "decimals" + | "description" + | "getRoundData" + | "latestRoundData" + | "maxPrice" + | "pool" + | "quoteAsset" + | "setMaxPrice" + | "twapInterval" + | "version" + ): FunctionFragment; + + encodeFunctionData(functionFragment: "baseAsset", values?: undefined): string; + encodeFunctionData(functionFragment: "decimals", values?: undefined): string; + encodeFunctionData( + functionFragment: "description", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getRoundData", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "latestRoundData", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "maxPrice", values?: undefined): string; + encodeFunctionData(functionFragment: "pool", values?: undefined): string; + encodeFunctionData( + functionFragment: "quoteAsset", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "setMaxPrice", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "twapInterval", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "version", values?: undefined): string; + + decodeFunctionResult(functionFragment: "baseAsset", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "description", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getRoundData", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "latestRoundData", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "maxPrice", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "pool", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "quoteAsset", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "setMaxPrice", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "twapInterval", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; + + events: {}; +} + +export interface IUniswapV3PriceFeed extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: IUniswapV3PriceFeedInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + baseAsset(overrides?: CallOverrides): Promise<[string]>; + + decimals(overrides?: CallOverrides): Promise<[number]>; + + description(overrides?: CallOverrides): Promise<[string]>; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + pool(overrides?: CallOverrides): Promise<[string]>; + + quoteAsset(overrides?: CallOverrides): Promise<[string]>; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise<[number]>; + + version(overrides?: CallOverrides): Promise<[BigNumber]>; + }; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + + callStatic: { + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: CallOverrides + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; + + filters: {}; + + estimateGas: { + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise; + + latestRoundData(overrides?: CallOverrides): Promise; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise; + + latestRoundData(overrides?: CallOverrides): Promise; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; +} diff --git a/packages/protocol/src/types/contracts/oracles/UniswapV3PriceFeed.ts b/packages/protocol/src/types/contracts/oracles/UniswapV3PriceFeed.ts new file mode 100644 index 00000000..8ed1ba4b --- /dev/null +++ b/packages/protocol/src/types/contracts/oracles/UniswapV3PriceFeed.ts @@ -0,0 +1,452 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from "../../common"; +import type { + FunctionFragment, + Result, + EventFragment, +} from "@ethersproject/abi"; +import type { Listener, Provider } from "@ethersproject/providers"; +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; + +export interface UniswapV3PriceFeedInterface extends utils.Interface { + functions: { + "_renounceOwnership()": FunctionFragment; + "_transferOwnership(address)": FunctionFragment; + "baseAsset()": FunctionFragment; + "decimals()": FunctionFragment; + "description()": FunctionFragment; + "getRoundData(uint80)": FunctionFragment; + "latestRoundData()": FunctionFragment; + "maxPrice()": FunctionFragment; + "owner()": FunctionFragment; + "pool()": FunctionFragment; + "quoteAsset()": FunctionFragment; + "setMaxPrice(int256)": FunctionFragment; + "twapInterval()": FunctionFragment; + "version()": FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | "_renounceOwnership" + | "_transferOwnership" + | "baseAsset" + | "decimals" + | "description" + | "getRoundData" + | "latestRoundData" + | "maxPrice" + | "owner" + | "pool" + | "quoteAsset" + | "setMaxPrice" + | "twapInterval" + | "version" + ): FunctionFragment; + + encodeFunctionData( + functionFragment: "_renounceOwnership", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "_transferOwnership", + values: [string] + ): string; + encodeFunctionData(functionFragment: "baseAsset", values?: undefined): string; + encodeFunctionData(functionFragment: "decimals", values?: undefined): string; + encodeFunctionData( + functionFragment: "description", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getRoundData", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "latestRoundData", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "maxPrice", values?: undefined): string; + encodeFunctionData(functionFragment: "owner", values?: undefined): string; + encodeFunctionData(functionFragment: "pool", values?: undefined): string; + encodeFunctionData( + functionFragment: "quoteAsset", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "setMaxPrice", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "twapInterval", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "version", values?: undefined): string; + + decodeFunctionResult( + functionFragment: "_renounceOwnership", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "_transferOwnership", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "baseAsset", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "description", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getRoundData", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "latestRoundData", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "maxPrice", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "pool", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "quoteAsset", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "setMaxPrice", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "twapInterval", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; + + events: { + "TransferOwnership(address,address)": EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: "TransferOwnership"): EventFragment; +} + +export interface TransferOwnershipEventObject { + oldOwner: string; + newOwner: string; +} +export type TransferOwnershipEvent = TypedEvent< + [string, string], + TransferOwnershipEventObject +>; + +export type TransferOwnershipEventFilter = + TypedEventFilter; + +export interface UniswapV3PriceFeed extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: UniswapV3PriceFeedInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + _renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise<[string]>; + + decimals(overrides?: CallOverrides): Promise<[number]>; + + description(overrides?: CallOverrides): Promise<[string]>; + + getRoundData( + roundId_: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + owner(overrides?: CallOverrides): Promise<[string]>; + + pool(overrides?: CallOverrides): Promise<[string]>; + + quoteAsset(overrides?: CallOverrides): Promise<[string]>; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise<[number]>; + + version(overrides?: CallOverrides): Promise<[BigNumber]>; + }; + + _renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + roundId_: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + + callStatic: { + _renounceOwnership(overrides?: CallOverrides): Promise; + + _transferOwnership( + newOwner: string, + overrides?: CallOverrides + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + roundId_: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: CallOverrides + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; + + filters: { + "TransferOwnership(address,address)"( + oldOwner?: string | null, + newOwner?: string | null + ): TransferOwnershipEventFilter; + TransferOwnership( + oldOwner?: string | null, + newOwner?: string | null + ): TransferOwnershipEventFilter; + }; + + estimateGas: { + _renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + roundId_: BigNumberish, + overrides?: CallOverrides + ): Promise; + + latestRoundData(overrides?: CallOverrides): Promise; + + maxPrice(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + _renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + roundId_: BigNumberish, + overrides?: CallOverrides + ): Promise; + + latestRoundData(overrides?: CallOverrides): Promise; + + maxPrice(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; +} diff --git a/packages/protocol/src/types/contracts/oracles/index.ts b/packages/protocol/src/types/contracts/oracles/index.ts index 51fefed1..e84afe34 100644 --- a/packages/protocol/src/types/contracts/oracles/index.ts +++ b/packages/protocol/src/types/contracts/oracles/index.ts @@ -3,5 +3,7 @@ /* eslint-disable */ export type { ChainlinkOperator } from "./ChainlinkOperator"; export type { IChainlinkOperator } from "./IChainlinkOperator"; +export type { IUniswapV3PriceFeed } from "./IUniswapV3PriceFeed"; export type { SimplePriceFeed } from "./SimplePriceFeed"; export type { StablecoinPriceFeed } from "./StablecoinPriceFeed"; +export type { UniswapV3PriceFeed } from "./UniswapV3PriceFeed"; diff --git a/packages/protocol/src/types/contracts/test/GodModeUniswapV3PriceFeed.ts b/packages/protocol/src/types/contracts/test/GodModeUniswapV3PriceFeed.ts new file mode 100644 index 00000000..f2211813 --- /dev/null +++ b/packages/protocol/src/types/contracts/test/GodModeUniswapV3PriceFeed.ts @@ -0,0 +1,486 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from "../../common"; +import type { FunctionFragment, Result } from "@ethersproject/abi"; +import type { Listener, Provider } from "@ethersproject/providers"; +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; + +export interface GodModeUniswapV3PriceFeedInterface extends utils.Interface { + functions: { + "__godMode_setMaxPrice(int256)": FunctionFragment; + "__godMode_setPool(address)": FunctionFragment; + "__godMode_setQuoteAsset(address)": FunctionFragment; + "__godMode_setTwapInterval(uint32)": FunctionFragment; + "baseAsset()": FunctionFragment; + "decimals()": FunctionFragment; + "description()": FunctionFragment; + "getRoundData(uint80)": FunctionFragment; + "latestRoundData()": FunctionFragment; + "maxPrice()": FunctionFragment; + "pool()": FunctionFragment; + "quoteAsset()": FunctionFragment; + "setMaxPrice(int256)": FunctionFragment; + "twapInterval()": FunctionFragment; + "version()": FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | "__godMode_setMaxPrice" + | "__godMode_setPool" + | "__godMode_setQuoteAsset" + | "__godMode_setTwapInterval" + | "baseAsset" + | "decimals" + | "description" + | "getRoundData" + | "latestRoundData" + | "maxPrice" + | "pool" + | "quoteAsset" + | "setMaxPrice" + | "twapInterval" + | "version" + ): FunctionFragment; + + encodeFunctionData( + functionFragment: "__godMode_setMaxPrice", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "__godMode_setPool", + values: [string] + ): string; + encodeFunctionData( + functionFragment: "__godMode_setQuoteAsset", + values: [string] + ): string; + encodeFunctionData( + functionFragment: "__godMode_setTwapInterval", + values: [BigNumberish] + ): string; + encodeFunctionData(functionFragment: "baseAsset", values?: undefined): string; + encodeFunctionData(functionFragment: "decimals", values?: undefined): string; + encodeFunctionData( + functionFragment: "description", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getRoundData", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "latestRoundData", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "maxPrice", values?: undefined): string; + encodeFunctionData(functionFragment: "pool", values?: undefined): string; + encodeFunctionData( + functionFragment: "quoteAsset", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "setMaxPrice", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "twapInterval", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "version", values?: undefined): string; + + decodeFunctionResult( + functionFragment: "__godMode_setMaxPrice", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "__godMode_setPool", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "__godMode_setQuoteAsset", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "__godMode_setTwapInterval", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "baseAsset", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "description", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getRoundData", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "latestRoundData", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "maxPrice", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "pool", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "quoteAsset", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "setMaxPrice", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "twapInterval", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; + + events: {}; +} + +export interface GodModeUniswapV3PriceFeed extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: GodModeUniswapV3PriceFeedInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + __godMode_setMaxPrice( + newMaxPrice: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setPool( + newPool: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setQuoteAsset( + newQuoteAsset: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setTwapInterval( + newTwapInterval: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise<[string]>; + + decimals(overrides?: CallOverrides): Promise<[number]>; + + description(overrides?: CallOverrides): Promise<[string]>; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + pool(overrides?: CallOverrides): Promise<[string]>; + + quoteAsset(overrides?: CallOverrides): Promise<[string]>; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise<[number]>; + + version(overrides?: CallOverrides): Promise<[BigNumber]>; + }; + + __godMode_setMaxPrice( + newMaxPrice: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setPool( + newPool: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setQuoteAsset( + newQuoteAsset: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setTwapInterval( + newTwapInterval: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + + callStatic: { + __godMode_setMaxPrice( + newMaxPrice: BigNumberish, + overrides?: CallOverrides + ): Promise; + + __godMode_setPool( + newPool: string, + overrides?: CallOverrides + ): Promise; + + __godMode_setQuoteAsset( + newQuoteAsset: string, + overrides?: CallOverrides + ): Promise; + + __godMode_setTwapInterval( + newTwapInterval: BigNumberish, + overrides?: CallOverrides + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + latestRoundData( + overrides?: CallOverrides + ): Promise< + [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { + roundId: BigNumber; + answer: BigNumber; + startedAt: BigNumber; + updatedAt: BigNumber; + answeredInRound: BigNumber; + } + >; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: CallOverrides + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; + + filters: {}; + + estimateGas: { + __godMode_setMaxPrice( + newMaxPrice: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setPool( + newPool: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setQuoteAsset( + newQuoteAsset: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setTwapInterval( + newTwapInterval: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise; + + latestRoundData(overrides?: CallOverrides): Promise; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + __godMode_setMaxPrice( + newMaxPrice: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setPool( + newPool: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setQuoteAsset( + newQuoteAsset: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + __godMode_setTwapInterval( + newTwapInterval: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + baseAsset(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + description(overrides?: CallOverrides): Promise; + + getRoundData( + _roundId: BigNumberish, + overrides?: CallOverrides + ): Promise; + + latestRoundData(overrides?: CallOverrides): Promise; + + maxPrice(overrides?: CallOverrides): Promise; + + pool(overrides?: CallOverrides): Promise; + + quoteAsset(overrides?: CallOverrides): Promise; + + setMaxPrice( + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + twapInterval(overrides?: CallOverrides): Promise; + + version(overrides?: CallOverrides): Promise; + }; +} diff --git a/packages/protocol/src/types/contracts/test/index.ts b/packages/protocol/src/types/contracts/test/index.ts index 315c66b1..d367c748 100644 --- a/packages/protocol/src/types/contracts/test/index.ts +++ b/packages/protocol/src/types/contracts/test/index.ts @@ -11,3 +11,4 @@ export type { GodModeErc20 } from "./GodModeErc20"; export type { GodModeFintroller } from "./GodModeFintroller"; export type { GodModeHToken } from "./GodModeHToken"; export type { GodModeOwnableUpgradeable } from "./GodModeOwnableUpgradeable"; +export type { GodModeUniswapV3PriceFeed } from "./GodModeUniswapV3PriceFeed"; diff --git a/packages/protocol/src/types/factories/contracts/external/common/index.ts b/packages/protocol/src/types/factories/contracts/external/common/index.ts new file mode 100644 index 00000000..2071ce5a --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/common/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { IERC20__factory } from "./IERC20__factory"; diff --git a/packages/protocol/src/types/factories/contracts/external/index.ts b/packages/protocol/src/types/factories/contracts/external/index.ts index 06ac8b56..dde8ebe2 100644 --- a/packages/protocol/src/types/factories/contracts/external/index.ts +++ b/packages/protocol/src/types/factories/contracts/external/index.ts @@ -2,3 +2,4 @@ /* tslint:disable */ /* eslint-disable */ export * as chainlink from "./chainlink"; +export * as uniswap from "./uniswap"; diff --git a/packages/protocol/src/types/factories/contracts/external/uniswap/index.ts b/packages/protocol/src/types/factories/contracts/external/uniswap/index.ts new file mode 100644 index 00000000..1d3444d5 --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/uniswap/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export * as interfaces from "./interfaces"; diff --git a/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/IUniswapV3Pool__factory.ts b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/IUniswapV3Pool__factory.ts new file mode 100644 index 00000000..9a078224 --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/IUniswapV3Pool__factory.ts @@ -0,0 +1,219 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + IUniswapV3Pool, + IUniswapV3PoolInterface, +} from "../../../../../contracts/external/uniswap/interfaces/IUniswapV3Pool"; +import type { Provider } from "@ethersproject/providers"; +import { Contract, Signer, utils } from "ethers"; + +const _abi = [ + { + inputs: [], + name: "factory", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "fee", + outputs: [ + { + internalType: "uint24", + name: "", + type: "uint24", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint160", + name: "sqrtPriceX96", + type: "uint160", + }, + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "maxLiquidityPerTick", + outputs: [ + { + internalType: "uint128", + name: "", + type: "uint128", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + ], + name: "observations", + outputs: [ + { + internalType: "uint32", + name: "blockTimestamp", + type: "uint32", + }, + { + internalType: "int56", + name: "tickCumulative", + type: "int56", + }, + { + internalType: "uint160", + name: "secondsPerLiquidityCumulativeX128", + type: "uint160", + }, + { + internalType: "bool", + name: "initialized", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint32[]", + name: "secondsAgos", + type: "uint32[]", + }, + ], + name: "observe", + outputs: [ + { + internalType: "int56[]", + name: "tickCumulatives", + type: "int56[]", + }, + { + internalType: "uint160[]", + name: "secondsPerLiquidityCumulativeX128s", + type: "uint160[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "slot0", + outputs: [ + { + internalType: "uint160", + name: "sqrtPriceX96", + type: "uint160", + }, + { + internalType: "int24", + name: "tick", + type: "int24", + }, + { + internalType: "uint16", + name: "observationIndex", + type: "uint16", + }, + { + internalType: "uint16", + name: "observationCardinality", + type: "uint16", + }, + { + internalType: "uint16", + name: "observationCardinalityNext", + type: "uint16", + }, + { + internalType: "uint8", + name: "feeProtocol", + type: "uint8", + }, + { + internalType: "bool", + name: "unlocked", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "tickSpacing", + outputs: [ + { + internalType: "int24", + name: "", + type: "int24", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "token0", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "token1", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, +]; + +export class IUniswapV3Pool__factory { + static readonly abi = _abi; + static createInterface(): IUniswapV3PoolInterface { + return new utils.Interface(_abi) as IUniswapV3PoolInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): IUniswapV3Pool { + return new Contract(address, _abi, signerOrProvider) as IUniswapV3Pool; + } +} diff --git a/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/index.ts b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/index.ts new file mode 100644 index 00000000..6eb02bbe --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { IUniswapV3Pool__factory } from "./IUniswapV3Pool__factory"; diff --git a/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState__factory.ts b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState__factory.ts new file mode 100644 index 00000000..89dce170 --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState__factory.ts @@ -0,0 +1,89 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + IUniswapV3PoolDerivedState, + IUniswapV3PoolDerivedStateInterface, +} from "../../../../../../contracts/external/uniswap/interfaces/pool/IUniswapV3PoolDerivedState"; +import type { Provider } from "@ethersproject/providers"; +import { Contract, Signer, utils } from "ethers"; + +const _abi = [ + { + inputs: [ + { + internalType: "uint32[]", + name: "secondsAgos", + type: "uint32[]", + }, + ], + name: "observe", + outputs: [ + { + internalType: "int56[]", + name: "tickCumulatives", + type: "int56[]", + }, + { + internalType: "uint160[]", + name: "secondsPerLiquidityCumulativeX128s", + type: "uint160[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "int24", + name: "tickLower", + type: "int24", + }, + { + internalType: "int24", + name: "tickUpper", + type: "int24", + }, + ], + name: "snapshotCumulativesInside", + outputs: [ + { + internalType: "int56", + name: "tickCumulativeInside", + type: "int56", + }, + { + internalType: "uint160", + name: "secondsPerLiquidityInsideX128", + type: "uint160", + }, + { + internalType: "uint32", + name: "secondsInside", + type: "uint32", + }, + ], + stateMutability: "view", + type: "function", + }, +]; + +export class IUniswapV3PoolDerivedState__factory { + static readonly abi = _abi; + static createInterface(): IUniswapV3PoolDerivedStateInterface { + return new utils.Interface(_abi) as IUniswapV3PoolDerivedStateInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): IUniswapV3PoolDerivedState { + return new Contract( + address, + _abi, + signerOrProvider + ) as IUniswapV3PoolDerivedState; + } +} diff --git a/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables__factory.ts b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables__factory.ts new file mode 100644 index 00000000..c88f528c --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables__factory.ts @@ -0,0 +1,109 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + IUniswapV3PoolImmutables, + IUniswapV3PoolImmutablesInterface, +} from "../../../../../../contracts/external/uniswap/interfaces/pool/IUniswapV3PoolImmutables"; +import type { Provider } from "@ethersproject/providers"; +import { Contract, Signer, utils } from "ethers"; + +const _abi = [ + { + inputs: [], + name: "factory", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "fee", + outputs: [ + { + internalType: "uint24", + name: "", + type: "uint24", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "maxLiquidityPerTick", + outputs: [ + { + internalType: "uint128", + name: "", + type: "uint128", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "tickSpacing", + outputs: [ + { + internalType: "int24", + name: "", + type: "int24", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "token0", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "token1", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, +]; + +export class IUniswapV3PoolImmutables__factory { + static readonly abi = _abi; + static createInterface(): IUniswapV3PoolImmutablesInterface { + return new utils.Interface(_abi) as IUniswapV3PoolImmutablesInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): IUniswapV3PoolImmutables { + return new Contract( + address, + _abi, + signerOrProvider + ) as IUniswapV3PoolImmutables; + } +} diff --git a/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/index.ts b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/index.ts new file mode 100644 index 00000000..190838c4 --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/external/uniswap/interfaces/pool/index.ts @@ -0,0 +1,5 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { IUniswapV3PoolDerivedState__factory } from "./IUniswapV3PoolDerivedState__factory"; +export { IUniswapV3PoolImmutables__factory } from "./IUniswapV3PoolImmutables__factory"; diff --git a/packages/protocol/src/types/factories/contracts/oracles/IUniswapV3PriceFeed__factory.ts b/packages/protocol/src/types/factories/contracts/oracles/IUniswapV3PriceFeed__factory.ts new file mode 100644 index 00000000..1c55be5b --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/oracles/IUniswapV3PriceFeed__factory.ts @@ -0,0 +1,237 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + IUniswapV3PriceFeed, + IUniswapV3PriceFeedInterface, +} from "../../../contracts/oracles/IUniswapV3PriceFeed"; +import type { Provider } from "@ethersproject/providers"; +import { Contract, Signer, utils } from "ethers"; + +const _abi = [ + { + inputs: [], + name: "IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero", + type: "error", + }, + { + inputs: [ + { + internalType: "contract IErc20", + name: "quoteAsset", + type: "address", + }, + ], + name: "IUniswapV3PriceFeed__QuoteAssetNotInPool", + type: "error", + }, + { + inputs: [], + name: "IUniswapV3PriceFeed__TwapCriteriaNotSatisfied", + type: "error", + }, + { + inputs: [], + name: "baseAsset", + outputs: [ + { + internalType: "contract IErc20", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "description", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint80", + name: "_roundId", + type: "uint80", + }, + ], + name: "getRoundData", + outputs: [ + { + internalType: "uint80", + name: "roundId", + type: "uint80", + }, + { + internalType: "int256", + name: "answer", + type: "int256", + }, + { + internalType: "uint256", + name: "startedAt", + type: "uint256", + }, + { + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + { + internalType: "uint80", + name: "answeredInRound", + type: "uint80", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "latestRoundData", + outputs: [ + { + internalType: "uint80", + name: "roundId", + type: "uint80", + }, + { + internalType: "int256", + name: "answer", + type: "int256", + }, + { + internalType: "uint256", + name: "startedAt", + type: "uint256", + }, + { + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + { + internalType: "uint80", + name: "answeredInRound", + type: "uint80", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "maxPrice", + outputs: [ + { + internalType: "int256", + name: "", + type: "int256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "pool", + outputs: [ + { + internalType: "contract IUniswapV3Pool", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "quoteAsset", + outputs: [ + { + internalType: "contract IErc20", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "int256", + name: "maxPrice_", + type: "int256", + }, + ], + name: "setMaxPrice", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "twapInterval", + outputs: [ + { + internalType: "uint32", + name: "", + type: "uint32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "version", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, +]; + +export class IUniswapV3PriceFeed__factory { + static readonly abi = _abi; + static createInterface(): IUniswapV3PriceFeedInterface { + return new utils.Interface(_abi) as IUniswapV3PriceFeedInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): IUniswapV3PriceFeed { + return new Contract(address, _abi, signerOrProvider) as IUniswapV3PriceFeed; + } +} diff --git a/packages/protocol/src/types/factories/contracts/oracles/UniswapV3PriceFeed__factory.ts b/packages/protocol/src/types/factories/contracts/oracles/UniswapV3PriceFeed__factory.ts new file mode 100644 index 00000000..9b447667 --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/oracles/UniswapV3PriceFeed__factory.ts @@ -0,0 +1,400 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + UniswapV3PriceFeed, + UniswapV3PriceFeedInterface, +} from "../../../contracts/oracles/UniswapV3PriceFeed"; +import type { Provider, TransactionRequest } from "@ethersproject/providers"; +import { + Signer, + utils, + Contract, + ContractFactory, + BigNumberish, + Overrides, +} from "ethers"; + +const _abi = [ + { + inputs: [ + { + internalType: "contract IUniswapV3Pool", + name: "pool_", + type: "address", + }, + { + internalType: "contract IErc20", + name: "quoteAsset_", + type: "address", + }, + { + internalType: "uint32", + name: "twapInterval_", + type: "uint32", + }, + { + internalType: "int256", + name: "maxPrice_", + type: "int256", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero", + type: "error", + }, + { + inputs: [ + { + internalType: "contract IErc20", + name: "quoteAsset", + type: "address", + }, + ], + name: "IUniswapV3PriceFeed__QuoteAssetNotInPool", + type: "error", + }, + { + inputs: [], + name: "IUniswapV3PriceFeed__TwapCriteriaNotSatisfied", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "caller", + type: "address", + }, + ], + name: "Ownable__NotOwner", + type: "error", + }, + { + inputs: [], + name: "Ownable__OwnerZeroAddress", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "TransferOwnership", + type: "event", + }, + { + inputs: [], + name: "_renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "_transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "baseAsset", + outputs: [ + { + internalType: "contract IErc20", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "description", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint80", + name: "roundId_", + type: "uint80", + }, + ], + name: "getRoundData", + outputs: [ + { + internalType: "uint80", + name: "roundId", + type: "uint80", + }, + { + internalType: "int256", + name: "answer", + type: "int256", + }, + { + internalType: "uint256", + name: "startedAt", + type: "uint256", + }, + { + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + { + internalType: "uint80", + name: "answeredInRound", + type: "uint80", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "latestRoundData", + outputs: [ + { + internalType: "uint80", + name: "roundId", + type: "uint80", + }, + { + internalType: "int256", + name: "answer", + type: "int256", + }, + { + internalType: "uint256", + name: "startedAt", + type: "uint256", + }, + { + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + { + internalType: "uint80", + name: "answeredInRound", + type: "uint80", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "maxPrice", + outputs: [ + { + internalType: "int256", + name: "", + type: "int256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "pool", + outputs: [ + { + internalType: "contract IUniswapV3Pool", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "quoteAsset", + outputs: [ + { + internalType: "contract IErc20", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "int256", + name: "maxPrice_", + type: "int256", + }, + ], + name: "setMaxPrice", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "twapInterval", + outputs: [ + { + internalType: "uint32", + name: "", + type: "uint32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "version", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, +]; + +const _bytecode = + "0x61018060405234620000b457620000236200001962000128565b9291909162000363565b6040516116e990816200087882396080518181816101c001526108a7015260a0518181816103900152611008015260c05181818161012b015281816108e60152611078015260e05181818161030a0152610f73015261010051815050610120518181816110d501526111680152610140518161109b0152610160518181816111100152818161119e01526111d60152f35b600080fd5b601f909101601f19168101906001600160401b03821190821017620000dd57604052565b5050634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811614156200010857565b50600080fd5b519063ffffffff82168214156200012157565b5050600080fd5b62001f6160808138039182604051938492620001458285620000b9565b833981010312620001215780516200015d81620000f5565b6020820151926200016e84620000f5565b60606200017e604085016200010e565b9301519193929190565b90816020910312620001215751620001a081620000f5565b90565b506040513d6000823e3d90fd5b519061ffff82168214156200012157565b519060ff82168214156200012157565b51908115158214156200012157565b908160e091031262000121578051620001f981620000f5565b9160208201518060020b8114156200025557916200021a60408201620001b0565b916200022960608301620001b0565b916200023860808201620001b0565b91620001a060c06200024d60a08501620001c1565b9301620001d1565b50505050600080fd5b50634e487b7160e01b600052601160045260246000fd5b61ffff6001911661fffe81116200028a570190565b620002946200025e565b0190565b9061ffff809116918215620002ac57160690565b50505050634e487b7160e01b600052601260045260246000fd5b91908260809103126200012157620002de826200010e565b9160208101518060060b811415620002555791620001a0606060408401516200024d81620000f5565b81811062000313570390565b6200031d6200025e565b0390565b600a9063ffffffff8091168091048211811515166200033e570290565b620003486200025e565b0290565b908160209103126200012157620001a090620001c1565b93929190620003716200083b565b60c05260408051630dfe168160e01b81526004956001600160a01b039190808316906020838a81855afa9283156200082b575b60009362000810575b50836101009316835283855163d21220a760e01b81526020818c81875afa90811562000800575b600091620007dd575b501661014081815260c051909591906001600160a01b0316855190919062000415906001600160a01b03165b6001600160a01b031690565b90838316918214159182620007d1575b505062000799575060c0518a9360e093909290916001600160a01b031687516001600160a01b03169180831691161460001462000793575084516001600160a01b03165b60805260a052855192838092633850c7bd851b82525afa801562000783575b88600092839084936200074e575b5060a051620004c69190620004c090620004b9906001600160a01b031662000409565b9562000275565b62000298565b6080875180958180620004f163252c09d760e01b9687835288830191909161ffff6020820193169052565b03915afa9384156200073e575b60009081956200071d575b5093156200068b575b50506200052763ffffffff8093164262000307565b6200054e620005476200053a8962000321565b63ffffffff607d91160490565b61ffff1690565b9287161191821562000678575b505062000665576000851315620006525790620005f49596620005cb6200040962000592620004096020965160018060a01b031690565b9386518681868163313ce56760e01b998a82525afa90811562000642575b60009162000629575b5061012052516001600160a01b031690565b93518094819382525afa90811562000619575b600091620005f6575b506101605260e052600155565b565b620006129150620006083d82620000b9565b3d8101906200034c565b38620005e7565b62000623620001a3565b620005de565b6200063b9150620006083d82620000b9565b38620005b9565b6200064c620001a3565b620005b0565b50505163119ced2160e21b815292505050fd5b50505163a99e764f60e01b815292505050fd5b61ffff908116911610905038806200055b565b60a051929350620006c7926080929190620006af906001600160a01b031662000409565b90885180958194829383528201906000602083019252565b03915afa9081156200070d575b600091620006e7575b5090883862000512565b620007039150620006f93d82620000b9565b3d810190620002c6565b50505038620006dd565b62000717620001a3565b620006d4565b905062000732919450620006f93d82620000b9565b95929150503862000509565b62000748620001a3565b620004fe565b9050620004c6935062000773919250620007693d82620000b9565b3d810190620001e0565b5050949350949150939062000496565b6200078d620001a3565b62000488565b62000469565b955163449d059d60e01b81526001600160a01b03909616998601998a525093978897506020019550620007cd945050505050565b0390fd5b14159050388062000425565b620007f99150620007ef3d82620000b9565b3d81019062000188565b38620003dd565b6200080a620001a3565b620003d4565b62000823919350620007ef3d82620000b9565b9138620003ad565b62000835620001a3565b620003a4565b3360018060a01b031960005416176000553360007f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c81604051a356fe6040608081526004361015610015575b50600080fd5b600090813560e01c806316f0115b1461036857806327163d4a14610351578063313ce567146103365780633c1d5df0146102f65780634b3f2889146102df57806354fd4d50146102c45780637284e4161461029d5780638da5cb5b1461024e5780639a6fc8f5146101fc578063cdf456e1146101ac578063d29d44ee14610192578063e38d6b5c1461016c578063fdf262b7146101175763feaf968c146100bc575061000f565b346101135761010f91506100cf366103de565b6100d76109e2565b945169ffffffffffffffffffff94851681526020810193909352604083019190915260608201529116608082015290819060a0820190565b0390f35b5080fd5b5090346101675750610128366103de565b517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168152602090f35b809150fd5b50346101135761010f9150610180366103de565b60015490519081529081906020820190565b5034610113576101a96101a436610523565b610622565b51f35b50903461016757506101bd366103de565b517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168152602090f35b509034610167575061020d366104b9565b61010f610218610f55565b925192839283608090600092949369ffffffffffffffffffff60a083019616825260208201528260408201528260608201520152565b50346101135773ffffffffffffffffffffffffffffffffffffffff61010f92610276366103de565b549151911673ffffffffffffffffffffffffffffffffffffffff1681529081906020820190565b50346101135761010f91506102b1366103de565b6102b961085d565b90519182918261046f565b50903461016757506102d5366103de565b5160018152602090f35b5034610113576102ee366103de565b6101a961055c565b5090346101675750610307366103de565b517f000000000000000000000000000000000000000000000000000000000000000063ffffffff168152602090f35b5090346101675750610347366103de565b5160088152602090f35b5034610113576101a96103633661040a565b6109f5565b5050346103db5750610379366103de565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166080527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8060a0016080f35b80fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc600091011261000f57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f5760043590565b918091926000905b82821061045a575011610453575050565b6000910152565b91508060209183015181860152018291610442565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604093602084526104b2815180928160208801526020888801910161043a565b0116010190565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f5760043569ffffffffffffffffffff81168114156104fd5790565b5050600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116141561000f57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602091011261000f5760043561055981610504565b90565b6000549073ffffffffffffffffffffffffffffffffffffffff821691338314156105d15760007fffffffffffffffffffffffff000000000000000000000000000000000000000092937f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c82604051a316600055565b50506040517fcc6bdb1d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152336024820152604490fd5b6000549073ffffffffffffffffffffffffffffffffffffffff80831691338314156106ce57169182156106a057827fffffffffffffffffffffffff0000000000000000000000000000000000000000927f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c6000604051a31617600055565b5050505060046040517f4208fc5d000000000000000000000000000000000000000000000000000000008152fd5b50506040517fcc6bdb1d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152336024820152604492509050fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761079357604052565b61079b610722565b604052565b60208183031261084857805167ffffffffffffffff9182821161083e57019082601f83011215610828578151908111610831575b6040519261080a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160185610752565b8184526020828401011161082857610559916020808501910161043a565b50505050600080fd5b610839610722565b6107d4565b5050505050600080fd5b505050600080fd5b506040513d6000823e3d90fd5b6040517f95d89b4100000000000000000000000000000000000000000000000000000000908181526000918273ffffffffffffffffffffffffffffffffffffffff918184600481867f0000000000000000000000000000000000000000000000000000000000000000165afa9384156109d5575b82946109ba575b5060046040518094819382527f0000000000000000000000000000000000000000000000000000000000000000165afa9283156109ad575b8093610982575b5050602361055991604051938161093886935180926020808701910161043a565b82017f202f2000000000000000000000000000000000000000000000000000000000006020820152610973825180936020878501910161043a565b01036003810184520182610752565b6105599293506023916109a6913d90823e61099d3d82610752565b3d8101906107a0565b9291610917565b6109b5610850565b610910565b6109ce9194503d83823e61099d3d82610752565b92386108d8565b6109dd610850565b6108d1565b6109ea610f55565b600091829042908290565b73ffffffffffffffffffffffffffffffffffffffff6000541633811415610a5157506000811315610a2557600155565b505060046040517f4673b484000000000000000000000000000000000000000000000000000000008152fd5b6040517fcc6bdb1d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152336024820152604492509050fd5b60209067ffffffffffffffff8111610abd575b60051b0190565b610ac5610722565b610ab6565b604051906060820182811067ffffffffffffffff821117610af8575b60405260028252604082602036910137565b610b00610722565b610ae6565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602090805115610b43570190565b610b4b610b05565b0190565b604090805160011015610b43570190565b81601f8201121561084857805191610b7783610aa3565b92610b856040519485610752565b808452602092838086019260051b820101928311610bc8578301905b828210610baf575050505090565b8380918351610bbd81610504565b815201910190610ba1565b505050505050600080fd5b9190916040818403126108485780519267ffffffffffffffff9384811161083e5782019381601f8601121561083e57845194610c0e86610aa3565b90610c1c6040519283610752565b868252602096878084019160051b83010191858311610c81578801905b828210610c58575050509483015190811161083e576105599201610b60565b81518060060b811415610c72578152908801908801610c39565b50505050505050505050600080fd5b505050505050505050600080fd5b6020908160408183019282815285518094520193019160005b828110610cb6575050505090565b835163ffffffff1685529381019392810192600101610ca8565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60060b9060060b9060008212827fffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000018212811516610d5a575b82667fffffffffffff01821316610d4e570390565b610d56610cd0565b0390565b610d62610cd0565b610d39565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60060b9060060b908115610e01575b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147fffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000821416610df5570590565b610dfd610cd0565b0590565b610e09610d67565b610da6565b60ff168060ff03600811610e23575b60080190565b610e2b610cd0565b610e1d565b60ff168060ff03601011610e45575b60100190565b610e4d610cd0565b610e3f565b60ff16604d8111610e64575b600a0a90565b610e6c610cd0565b610e5e565b8015610e96575b78010000000000000000000000000000000000000000000000000490565b610e9e610d67565b610e78565b8015610ecf575b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0490565b610ed7610d67565b610eaa565b8115610ee6570490565b610eee610d67565b0490565b8115610f48575b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f8000000000000000000000000000000000000000000000000000000000000000821416610df5570590565b610f50610d67565b610ef9565b610fe961107661107161106b610f69610aca565b63ffffffff6110607f000000000000000000000000000000000000000000000000000000000000000092610fab84610fa083610b35565b9063ffffffff169052565b6000610fb682610b4f565b526040519788917f883bdbfd00000000000000000000000000000000000000000000000000000000835260048301610c8f565b039660008173ffffffffffffffffffffffffffffffffffffffff99818b7f0000000000000000000000000000000000000000000000000000000000000000165afa90811561121c575b6000916111fa575b5061105a61104d61105461104d84610b4f565b5160060b90565b92610b35565b90610d00565b911660030b90610d97565b60020b90565b61133e565b7f000000000000000000000000000000000000000000000000000000000000000082167f0000000000000000000000000000000000000000000000000000000000000000831614156111595761110b9061113a926111036110fe6110f97f0000000000000000000000000000000000000000000000000000000000000000610e0e565b610e52565b610e71565b911680611230565b6111347f0000000000000000000000000000000000000000000000000000000000000000610e52565b90610edc565b905b6001548083136111555750811561114f57565b60019150565b9150565b61118c916111036110fe6110f97f0000000000000000000000000000000000000000000000000000000000000000610e0e565b80156111cd576111c7906111c26110f97f0000000000000000000000000000000000000000000000000000000000000000610e30565b610ef2565b9061113c565b506105596110f97f0000000000000000000000000000000000000000000000000000000000000000610e30565b611215913d90823e61120c3d82610752565b3d810190610bd3565b503861103a565b611224610850565b611032565b1561000f57565b90917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83830992808302928380861095039480860395146112c957908291611279868411611229565b096001821901821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b50509150610eee821515611229565b156112df57565b5060646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f54000000000000000000000000000000000000000000000000000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff9060020b60008112156116c85780600003905b611375620d89e88311156112d8565b600182161561169f5770ffffffffffffffffffffffffffffffffff6ffffcb933bd6fad37aa2d162d1a5940015b169160028116611683575b60048116611667575b6008811661164b575b6010811661162f575b60208116611613575b604081166115f7575b6080908181166115dc575b61010081166115c1575b61020081166115a6575b610400811661158b575b6108008116611570575b6110008116611555575b612000811661153a575b614000811661151f575b6180008116611504575b6201000081166114e9575b6202000081166114cf575b6204000081166114b5575b620800001661149a575b5060001261148c575b63ffffffff81166114835760ff60005b169060201c011690565b60ff6001611479565b61149590610ea3565b611469565b6b048a170391f7dc42444e8fa26000929302901c9190611460565b6d2216e584f5fa1ea926041bedfe98909302811c92611456565b926e5d6af8dedb81196699c329225ee60402811c9261144b565b926f09aa508b5b7a84e1c677de54f3e99bc902811c92611440565b926f31be135f97d08fd981231505542fcfa602811c92611435565b926f70d869a156d2a1b890bb3df62baf32f702811c9261142b565b926fa9f746462d870fdf8a65dc1f90e061e502811c92611421565b926fd097f3bdfd2022b8845ad8f792aa582502811c92611417565b926fe7159475a2c29b7443b29c7fa6e889d902811c9261140d565b926ff3392b0822b70005940c7a398e4b70f302811c92611403565b926ff987a7253ac413176f2b074cf7815e5402811c926113f9565b926ffcbe86c7900a88aedcffc83b479aa3a402811c926113ef565b926ffe5dee046a99a2a811c461f1969c305302811c926113e5565b916fff2ea16466c96a3843ec78b326b528610260801c916113da565b916fff973b41fa98c081472e6896dfb254c00260801c916113d1565b916fffcb9843d60f6159c9db58835c9266440260801c916113c8565b916fffe5caca7e10e4e61c3624eaa0941cd00260801c916113bf565b916ffff2e50f5f656932ef12357cf3c7fdcc0260801c916113b6565b916ffff97272373d413259a46990580e213a0260801c916113ad565b70ffffffffffffffffffffffffffffffffff7001000000000000000000000000000000006113a2565b8061136656fea26c6578706572696d656e74616cf564736f6c634300080c0018"; + +type UniswapV3PriceFeedConstructorParams = + | [signer?: Signer] + | ConstructorParameters; + +const isSuperArgs = ( + xs: UniswapV3PriceFeedConstructorParams +): xs is ConstructorParameters => xs.length > 1; + +export class UniswapV3PriceFeed__factory extends ContractFactory { + constructor(...args: UniswapV3PriceFeedConstructorParams) { + if (isSuperArgs(args)) { + super(...args); + } else { + super(_abi, _bytecode, args[0]); + } + } + + override deploy( + pool_: string, + quoteAsset_: string, + twapInterval_: BigNumberish, + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise { + return super.deploy( + pool_, + quoteAsset_, + twapInterval_, + maxPrice_, + overrides || {} + ) as Promise; + } + override getDeployTransaction( + pool_: string, + quoteAsset_: string, + twapInterval_: BigNumberish, + maxPrice_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): TransactionRequest { + return super.getDeployTransaction( + pool_, + quoteAsset_, + twapInterval_, + maxPrice_, + overrides || {} + ); + } + override attach(address: string): UniswapV3PriceFeed { + return super.attach(address) as UniswapV3PriceFeed; + } + override connect(signer: Signer): UniswapV3PriceFeed__factory { + return super.connect(signer) as UniswapV3PriceFeed__factory; + } + + static readonly bytecode = _bytecode; + static readonly abi = _abi; + static createInterface(): UniswapV3PriceFeedInterface { + return new utils.Interface(_abi) as UniswapV3PriceFeedInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): UniswapV3PriceFeed { + return new Contract(address, _abi, signerOrProvider) as UniswapV3PriceFeed; + } +} diff --git a/packages/protocol/src/types/factories/contracts/oracles/index.ts b/packages/protocol/src/types/factories/contracts/oracles/index.ts index 8833d116..899dafd4 100644 --- a/packages/protocol/src/types/factories/contracts/oracles/index.ts +++ b/packages/protocol/src/types/factories/contracts/oracles/index.ts @@ -3,5 +3,7 @@ /* eslint-disable */ export { ChainlinkOperator__factory } from "./ChainlinkOperator__factory"; export { IChainlinkOperator__factory } from "./IChainlinkOperator__factory"; +export { IUniswapV3PriceFeed__factory } from "./IUniswapV3PriceFeed__factory"; export { SimplePriceFeed__factory } from "./SimplePriceFeed__factory"; export { StablecoinPriceFeed__factory } from "./StablecoinPriceFeed__factory"; +export { UniswapV3PriceFeed__factory } from "./UniswapV3PriceFeed__factory"; diff --git a/packages/protocol/src/types/factories/contracts/test/GodModeUniswapV3PriceFeed__factory.ts b/packages/protocol/src/types/factories/contracts/test/GodModeUniswapV3PriceFeed__factory.ts new file mode 100644 index 00000000..dbfdae6f --- /dev/null +++ b/packages/protocol/src/types/factories/contracts/test/GodModeUniswapV3PriceFeed__factory.ts @@ -0,0 +1,382 @@ +/* Autogenerated file. Do not edit manually. */ + +/* tslint:disable */ + +/* eslint-disable */ +import type { + GodModeUniswapV3PriceFeed, + GodModeUniswapV3PriceFeedInterface, +} from "../../../contracts/test/GodModeUniswapV3PriceFeed"; +import type { Provider, TransactionRequest } from "@ethersproject/providers"; +import { + Signer, + utils, + Contract, + ContractFactory, + BigNumberish, + Overrides, +} from "ethers"; + +const _abi = [ + { + inputs: [ + { + internalType: "contract IUniswapV3Pool", + name: "pool_", + type: "address", + }, + { + internalType: "contract IErc20", + name: "quoteAsset_", + type: "address", + }, + { + internalType: "uint32", + name: "twapInterval_", + type: "uint32", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "IUniswapV3PriceFeed__MaxPriceLessThanOrEqualToZero", + type: "error", + }, + { + inputs: [ + { + internalType: "contract IErc20", + name: "quoteAsset", + type: "address", + }, + ], + name: "IUniswapV3PriceFeed__QuoteAssetNotInPool", + type: "error", + }, + { + inputs: [], + name: "IUniswapV3PriceFeed__TwapCriteriaNotSatisfied", + type: "error", + }, + { + stateMutability: "payable", + type: "fallback", + }, + { + inputs: [ + { + internalType: "int256", + name: "newMaxPrice", + type: "int256", + }, + ], + name: "__godMode_setMaxPrice", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IUniswapV3Pool", + name: "newPool", + type: "address", + }, + ], + name: "__godMode_setPool", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IErc20", + name: "newQuoteAsset", + type: "address", + }, + ], + name: "__godMode_setQuoteAsset", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint32", + name: "newTwapInterval", + type: "uint32", + }, + ], + name: "__godMode_setTwapInterval", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "baseAsset", + outputs: [ + { + internalType: "contract IErc20", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "description", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint80", + name: "_roundId", + type: "uint80", + }, + ], + name: "getRoundData", + outputs: [ + { + internalType: "uint80", + name: "roundId", + type: "uint80", + }, + { + internalType: "int256", + name: "answer", + type: "int256", + }, + { + internalType: "uint256", + name: "startedAt", + type: "uint256", + }, + { + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + { + internalType: "uint80", + name: "answeredInRound", + type: "uint80", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "latestRoundData", + outputs: [ + { + internalType: "uint80", + name: "roundId", + type: "uint80", + }, + { + internalType: "int256", + name: "answer", + type: "int256", + }, + { + internalType: "uint256", + name: "startedAt", + type: "uint256", + }, + { + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + { + internalType: "uint80", + name: "answeredInRound", + type: "uint80", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "maxPrice", + outputs: [ + { + internalType: "int256", + name: "", + type: "int256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "pool", + outputs: [ + { + internalType: "contract IUniswapV3Pool", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "quoteAsset", + outputs: [ + { + internalType: "contract IErc20", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "int256", + name: "maxPrice_", + type: "int256", + }, + ], + name: "setMaxPrice", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "twapInterval", + outputs: [ + { + internalType: "uint32", + name: "", + type: "uint32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "version", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, +]; + +const _bytecode = + "0x60806040523480156200001157600080fd5b5060405162004b1538038062004b158339810160408190526200003491620000e5565b8282826001600160ff1b036040516200004d90620000be565b6001600160a01b03948516815293909216602084015263ffffffff1660408301526060820152608001604051809103906000f08015801562000093573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b03929092169190911790555062000141915050565b611c338062002ee283390190565b6001600160a01b0381168114620000e257600080fd5b50565b600080600060608486031215620000fb57600080fd5b83516200010881620000cc565b60208501519093506200011b81620000cc565b604085015190925063ffffffff811681146200013657600080fd5b809150509250925092565b612d9180620001516000396000f3fe608060405260043610620001035760003560e01c806399f12c861162000097578063e38cfe7e1162000061578063e38cfe7e1462000385578063e38d6b5c14620003aa578063fdf262b714620003c2578063feaf968c14620003da576200017a565b806399f12c8614620002c65780639a6fc8f514620002eb5780639e868b4e1462000348578063cdf456e1146200036d576200017a565b80633c1d5df011620000d95780633c1d5df0146200022557806354fd4d5014620002535780637284e416146200027a57806396fce27714620002a1576200017a565b806316f0115b146200019e57806327163d4a14620001d3578063313ce56714620001fa576200017a565b366200017a57600080546040516001600160a01b039091169034905b60006040518083038185875af1925050503d80600081146200015e576040519150601f19603f3d011682016040523d82523d6000602084013e62000163565b606091505b505090508062000177576200017762000e52565b50005b600080546040516001600160a01b039091169034906200011f908490369062000e68565b348015620001ab57600080fd5b50620001b6620003f2565b6040516001600160a01b0390911681526020015b60405180910390f35b348015620001e057600080fd5b50620001f8620001f236600462000e78565b62000472565b005b3480156200020757600080fd5b5062000212620004d5565b60405160ff9091168152602001620001ca565b3480156200023257600080fd5b506200023d62000550565b60405163ffffffff9091168152602001620001ca565b3480156200026057600080fd5b506200026b620005cb565b604051908152602001620001ca565b3480156200028757600080fd5b506200029262000646565b604051620001ca919062000ec5565b348015620002ae57600080fd5b50620001f8620002c036600462000f10565b620006ba565b348015620002d357600080fd5b50620001f8620002e536600462000e78565b620008aa565b348015620002f857600080fd5b50620003106200030a36600462000f50565b62000a21565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a001620001ca565b3480156200035557600080fd5b50620001f86200036736600462000f86565b62000ab7565b3480156200037a57600080fd5b50620001b662000bf1565b3480156200039257600080fd5b50620001f8620003a436600462000f86565b62000c46565b348015620003b757600080fd5b506200026b62000d08565b348015620003cf57600080fd5b50620001b662000d5d565b348015620003e757600080fd5b506200031062000db2565b60008060009054906101000a90046001600160a01b03166001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000447573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200046d919062000fa6565b905090565b60005460405163138b1ea560e11b8152600481018390526001600160a01b03909116906327163d4a90602401600060405180830381600087803b158015620004b957600080fd5b505af1158015620004ce573d6000803e3d6000fd5b5050505050565b60008060009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200052a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200046d919062000fc6565b60008060009054906101000a90046001600160a01b03166001600160a01b0316633c1d5df06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620005a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200046d919062000feb565b60008060009054906101000a90046001600160a01b03166001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000620573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200046d91906200100b565b6000805460408051633942720b60e11b815290516060936001600160a01b0390931692637284e41692600480820193918290030181865afa15801562000690573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200046d91908101906200103b565b60008054906101000a90046001600160a01b03166001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200070c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000732919062000fa6565b60008054906101000a90046001600160a01b03166001600160a01b031663fdf262b76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000784573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007aa919062000fa6565b600054604080516338e35ad760e21b8152905185926001600160a01b03169163e38d6b5c9160048083019260209291908290030181865afa158015620007f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200081a91906200100b565b604051620008289062000e44565b6001600160a01b03948516815293909216602084015263ffffffff1660408301526060820152608001604051809103906000f0801580156200086e573d6000803e3d6000fd5b50600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905550565b60008054906101000a90046001600160a01b03166001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620008fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000922919062000fa6565b60008054906101000a90046001600160a01b03166001600160a01b031663fdf262b76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200099a919062000fa6565b60008054906101000a90046001600160a01b03166001600160a01b0316633c1d5df06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620009ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a12919062000feb565b83604051620008289062000e44565b60008054604051639a6fc8f560e01b815269ffffffffffffffffffff8416600482015282918291829182916001600160a01b0390911690639a6fc8f59060240160a060405180830381865afa15801562000a7f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000aa59190620010f4565b939a9299509097509550909350915050565b6000546040805163fdf262b760e01b8152905183926001600160a01b03169163fdf262b79160048083019260209291908290030181865afa15801562000b01573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b27919062000fa6565b60008054906101000a90046001600160a01b03166001600160a01b0316633c1d5df06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f919062000feb565b60008054906101000a90046001600160a01b03166001600160a01b031663e38d6b5c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007f4573d6000803e3d6000fd5b60008060009054906101000a90046001600160a01b03166001600160a01b031663cdf456e16040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000447573d6000803e3d6000fd5b60008054906101000a90046001600160a01b03166001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000c98573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cbe919062000fa6565b600054604080516303c1d5df60e41b8152905184926001600160a01b031691633c1d5df09160048083019260209291908290030181865afa15801562000b79573d6000803e3d6000fd5b60008060009054906101000a90046001600160a01b03166001600160a01b031663e38d6b5c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000620573d6000803e3d6000fd5b60008060009054906101000a90046001600160a01b03166001600160a01b031663fdf262b76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000447573d6000803e3d6000fd5b60008060008060008060009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562000e0d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e339190620010f4565b945094509450945094509091929394565b611c33806200115283390190565b634e487b7160e01b600052600160045260246000fd5b8183823760009101908152919050565b60006020828403121562000e8b57600080fd5b5035919050565b60005b8381101562000eaf57818101518382015260200162000e95565b8381111562000ebf576000848401525b50505050565b602081526000825180602084015262000ee681604085016020870162000e92565b601f01601f19169190910160400192915050565b63ffffffff8116811462000f0d57600080fd5b50565b60006020828403121562000f2357600080fd5b813562000f308162000efa565b9392505050565b69ffffffffffffffffffff8116811462000f0d57600080fd5b60006020828403121562000f6357600080fd5b813562000f308162000f37565b6001600160a01b038116811462000f0d57600080fd5b60006020828403121562000f9957600080fd5b813562000f308162000f70565b60006020828403121562000fb957600080fd5b815162000f308162000f70565b60006020828403121562000fd957600080fd5b815160ff8116811462000f3057600080fd5b60006020828403121562000ffe57600080fd5b815162000f308162000efa565b6000602082840312156200101e57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156200104e57600080fd5b815167ffffffffffffffff808211156200106757600080fd5b818401915084601f8301126200107c57600080fd5b81518181111562001091576200109162001025565b604051601f8201601f19908116603f01168101908382118183101715620010bc57620010bc62001025565b81604052828152876020848701011115620010d657600080fd5b620010e983602083016020880162000e92565b979650505050505050565b600080600080600060a086880312156200110d57600080fd5b85516200111a8162000f37565b809550506020860151935060408601519250606086015191506080860151620011438162000f37565b80915050929550929590935056fe6101806040523480156200001257600080fd5b5060405162001c3338038062001c3383398101604081905262000035916200057d565b600080546001600160a01b031916339081178255604051909182917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908290a350826001600160a01b031660c0816001600160a01b031681525050836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000cf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f59190620005d4565b6001600160a01b0316610100816001600160a01b031681525050836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200014e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001749190620005d4565b6001600160a01b03908116610140526101005160c0518216911614801590620001b45750610140516001600160a01b031660c0516001600160a01b031614155b15620001e65760c05160405163449d059d60e01b81526001600160a01b03909116600482015260240160405180910390fd5b610140516001600160a01b031660c0516001600160a01b0316146200020f576101405162000214565b610100515b6001600160a01b03908116608052841660a081905260408051633850c7bd60e01b8152905160009283928392633850c7bd9160048082019260e0929091908290030181865afa1580156200026c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000292919062000631565b5050945094509450505060008060a0516001600160a01b031663252c09d785876001620002c09190620006e7565b620002cc919062000726565b6040516001600160e01b031960e084901b16815261ffff9091166004820152602401608060405180830381865afa1580156200030c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200033291906200074a565b93505050915080620003b55760a05160405163252c09d760e01b8152600060048201526001600160a01b039091169063252c09d790602401608060405180830381865afa15801562000388573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ae91906200074a565b5091935050505b6000620003c963ffffffff841642620007b1565b90506000607d620003dc8a600a620007cb565b620003e89190620007fa565b90508863ffffffff168210806200040657508061ffff168561ffff16105b15620004255760405163a99e764f60e01b815260040160405180910390fd5b60008813620004475760405163119ced2160e21b815260040160405180910390fd5b610100516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000489573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004af919062000820565b60ff166101208160ff1681525050610140516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000525919062000820565b60ff166101605250505063ffffffff90951660e052505050600155506200083e915050565b6001600160a01b03811681146200056057600080fd5b50565b805163ffffffff811681146200057857600080fd5b919050565b600080600080608085870312156200059457600080fd5b8451620005a1816200054a565b6020860151909450620005b4816200054a565b9250620005c46040860162000563565b6060959095015193969295505050565b600060208284031215620005e757600080fd5b8151620005f4816200054a565b9392505050565b805161ffff811681146200057857600080fd5b805160ff811681146200057857600080fd5b805180151581146200057857600080fd5b600080600080600080600060e0888a0312156200064d57600080fd5b87516200065a816200054a565b8097505060208801518060020b81146200067357600080fd5b95506200068360408901620005fb565b94506200069360608901620005fb565b9350620006a360808901620005fb565b9250620006b360a089016200060e565b9150620006c360c0890162000620565b905092959891949750929550565b634e487b7160e01b600052601160045260246000fd5b600061ffff808316818516808303821115620007075762000707620006d1565b01949350505050565b634e487b7160e01b600052601260045260246000fd5b600061ffff808416806200073e576200073e62000710565b92169190910692915050565b600080600080608085870312156200076157600080fd5b6200076c8562000563565b935060208501518060060b81146200078357600080fd5b604086015190935062000796816200054a565b9150620007a66060860162000620565b905092959194509250565b600082821015620007c657620007c6620006d1565b500390565b600063ffffffff80831681851681830481118215151615620007f157620007f1620006d1565b02949350505050565b600063ffffffff8084168062000814576200081462000710565b92169190910492915050565b6000602082840312156200083357600080fd5b620005f4826200060e565b60805160a05160c05160e05161010051610120516101405161016051611354620008df600039600081816107ef015281816108d701526109170152600061079201526000818161082801526108a50152600050506000818161015c0152818161060401526107150152600081816102660152818161041c01526107bc01526000818160f40152610694015260008181610223015261039601526113546000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063d29d44ee11610066578063d29d44ee14610245578063e38d6b5c14610258578063fdf262b714610261578063feaf968c1461028857600080fd5b80638da5cb5b146101c15780639a6fc8f5146101d4578063cdf456e11461021e57600080fd5b80633c1d5df0116100c85780633c1d5df0146101575780634b3f28891461019357806354fd4d501461019b5780637284e416146101ac57600080fd5b806316f0115b146100ef57806327163d4a14610133578063313ce56714610148575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610146610141366004610d77565b610290565b005b6040516008815260200161012a565b61017e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161012a565b6101466102fb565b60015b60405190815260200161012a565b6101b4610392565b60405161012a9190610dc0565b600054610116906001600160a01b031681565b6101e76101e2366004610df3565b6104c5565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161012a565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610146610253366004610e37565b6104ea565b61019e60015481565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6101e76105b9565b6000546001600160a01b031633146102d55760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044015b60405180910390fd5b600081136102f65760405163119ced2160e21b815260040160405180910390fd5b600155565b6000546001600160a01b0316331461033b5760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044016102cc565b600080546040516001600160a01b03909116907f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60607f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156103f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261041a9190810190610e9b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610478573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104a09190810190610e9b565b6040516020016104b1929190610f2f565b604051602081830303815290604052905090565b6000806000806000856104d66105dd565b909790965060009550859450849350915050565b6000546001600160a01b0316331461052a5760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044016102cc565b6001600160a01b03811661055157604051634208fc5d60e01b815260040160405180910390fd5b600080546040516001600160a01b03808516939216917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c91a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000806000806000806105ca6105dd565b9096909550600094504293508492509050565b604080516002808252606082018352600092839291906020830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061063657610636610f6d565b602002602001019063ffffffff16908163ffffffff168152505060008160018151811061066557610665610f6d565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063883bdbfd906106c9908590600401610f83565b600060405180830381865afa1580156106e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261070e9190810190611065565b50905060007f000000000000000000000000000000000000000000000000000000000000000060030b8260008151811061074a5761074a610f6d565b60200260200101518360018151811061076557610765610f6d565b60200260200101516107779190611147565b61078191906111ad565b9050600061078e82610982565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161415610892576108157f0000000000000000000000000000000000000000000000000000000000000000600a6112d1565b6108816001600160a01b0383168061084e7f000000000000000000000000000000000000000000000000000000000000000060086112e0565b61085990600a6112d1565b61087c907801000000000000000000000000000000000000000000000000611305565b610cc2565b61088b9190611305565b9450610955565b6108cb6001600160a01b0382168061084e7f000000000000000000000000000000000000000000000000000000000000000060086112e0565b945084610911576108fd7f000000000000000000000000000000000000000000000000000000000000000060106112e0565b61090890600a6112d1565b94505050505090565b8461093d7f000000000000000000000000000000000000000000000000000000000000000060106112e0565b61094890600a6112d1565b6109529190611319565b94505b60015485131561096b5760015494505050505090565b8461097b57600194505050505090565b5050505090565b60008060008360020b12610999578260020b6109a1565b8260020b6000035b9050620d89e88111156109da5760405162461bcd60e51b81526020600482015260016024820152601560fa1b60448201526064016102cc565b6000600182166109fb57700100000000000000000000000000000000610a0d565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610a41576ffff97272373d413259a46990580e213a0260801c5b6004821615610a60576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610a7f576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615610a9e576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615610abd576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615610adc576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610afb576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610b1b576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610b3b576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610b5b576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610b7b576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610b9b576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610bbb576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610bdb576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610bfb576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610c1c576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610c3c576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610c5b576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610c78576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610c99578060001981610c9557610c95611197565b0490505b640100000000810615610cad576001610cb0565b60005b60ff16602082901c0192505050919050565b600080806000198587098587029250828110838203039150508060001415610cfc5760008411610cf157600080fd5b508290049050610d70565b808411610d0857600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600060208284031215610d8957600080fd5b5035919050565b60005b83811015610dab578181015183820152602001610d93565b83811115610dba576000848401525b50505050565b6020815260008251806020840152610ddf816040850160208701610d90565b601f01601f19169190910160400192915050565b600060208284031215610e0557600080fd5b813569ffffffffffffffffffff81168114610d7057600080fd5b6001600160a01b0381168114610e3457600080fd5b50565b600060208284031215610e4957600080fd5b8135610d7081610e1f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610e9357610e93610e54565b604052919050565b600060208284031215610ead57600080fd5b815167ffffffffffffffff80821115610ec557600080fd5b818401915084601f830112610ed957600080fd5b815181811115610eeb57610eeb610e54565b610efe601f8201601f1916602001610e6a565b9150808252856020828501011115610f1557600080fd5b610f26816020840160208601610d90565b50949350505050565b60008351610f41818460208801610d90565b6201017960ed1b9083019081528351610f61816003840160208801610d90565b01600301949350505050565b634e487b7160e01b600052603260045260246000fd5b6020808252825182820181905260009190848201906040850190845b81811015610fc157835163ffffffff1683529284019291840191600101610f9f565b50909695505050505050565b600067ffffffffffffffff821115610fe757610fe7610e54565b5060051b60200190565b600082601f83011261100257600080fd5b8151602061101761101283610fcd565b610e6a565b82815260059290921b8401810191818101908684111561103657600080fd5b8286015b8481101561105a57805161104d81610e1f565b835291830191830161103a565b509695505050505050565b6000806040838503121561107857600080fd5b825167ffffffffffffffff8082111561109057600080fd5b818501915085601f8301126110a457600080fd5b815160206110b461101283610fcd565b82815260059290921b840181019181810190898411156110d357600080fd5b948201945b838610156111015785518060060b81146110f25760008081fd5b825294820194908201906110d8565b9188015191965090935050508082111561111a57600080fd5b5061112785828601610ff1565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160060b8360060b6000811281667fffffffffffff190183128115161561117257611172611131565b81667fffffffffffff01831381161561118d5761118d611131565b5090039392505050565b634e487b7160e01b600052601260045260246000fd5b60008160060b8360060b806111c4576111c4611197565b667fffffffffffff198214600019821416156111e2576111e2611131565b90059392505050565b600181815b8085111561122657816000190482111561120c5761120c611131565b8085161561121957918102915b93841c93908002906111f0565b509250929050565b60008261123d575060016112cb565b8161124a575060006112cb565b8160018114611260576002811461126a57611286565b60019150506112cb565b60ff84111561127b5761127b611131565b50506001821b6112cb565b5060208310610133831016604e8410600b84101617156112a9575081810a6112cb565b6112b383836111eb565b80600019048211156112c7576112c7611131565b0290505b92915050565b6000610d7060ff84168361122e565b600060ff821660ff84168060ff038211156112fd576112fd611131565b019392505050565b60008261131457611314611197565b500490565b60008261132857611328611197565b600160ff1b82146000198414161561134257611342611131565b50059056fea164736f6c634300080c000aa164736f6c634300080c000a6101806040523480156200001257600080fd5b5060405162001c3338038062001c3383398101604081905262000035916200057d565b600080546001600160a01b031916339081178255604051909182917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908290a350826001600160a01b031660c0816001600160a01b031681525050836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000cf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f59190620005d4565b6001600160a01b0316610100816001600160a01b031681525050836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200014e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001749190620005d4565b6001600160a01b03908116610140526101005160c0518216911614801590620001b45750610140516001600160a01b031660c0516001600160a01b031614155b15620001e65760c05160405163449d059d60e01b81526001600160a01b03909116600482015260240160405180910390fd5b610140516001600160a01b031660c0516001600160a01b0316146200020f576101405162000214565b610100515b6001600160a01b03908116608052841660a081905260408051633850c7bd60e01b8152905160009283928392633850c7bd9160048082019260e0929091908290030181865afa1580156200026c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000292919062000631565b5050945094509450505060008060a0516001600160a01b031663252c09d785876001620002c09190620006e7565b620002cc919062000726565b6040516001600160e01b031960e084901b16815261ffff9091166004820152602401608060405180830381865afa1580156200030c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200033291906200074a565b93505050915080620003b55760a05160405163252c09d760e01b8152600060048201526001600160a01b039091169063252c09d790602401608060405180830381865afa15801562000388573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ae91906200074a565b5091935050505b6000620003c963ffffffff841642620007b1565b90506000607d620003dc8a600a620007cb565b620003e89190620007fa565b90508863ffffffff168210806200040657508061ffff168561ffff16105b15620004255760405163a99e764f60e01b815260040160405180910390fd5b60008813620004475760405163119ced2160e21b815260040160405180910390fd5b610100516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000489573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004af919062000820565b60ff166101208160ff1681525050610140516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000525919062000820565b60ff166101605250505063ffffffff90951660e052505050600155506200083e915050565b6001600160a01b03811681146200056057600080fd5b50565b805163ffffffff811681146200057857600080fd5b919050565b600080600080608085870312156200059457600080fd5b8451620005a1816200054a565b6020860151909450620005b4816200054a565b9250620005c46040860162000563565b6060959095015193969295505050565b600060208284031215620005e757600080fd5b8151620005f4816200054a565b9392505050565b805161ffff811681146200057857600080fd5b805160ff811681146200057857600080fd5b805180151581146200057857600080fd5b600080600080600080600060e0888a0312156200064d57600080fd5b87516200065a816200054a565b8097505060208801518060020b81146200067357600080fd5b95506200068360408901620005fb565b94506200069360608901620005fb565b9350620006a360808901620005fb565b9250620006b360a089016200060e565b9150620006c360c0890162000620565b905092959891949750929550565b634e487b7160e01b600052601160045260246000fd5b600061ffff808316818516808303821115620007075762000707620006d1565b01949350505050565b634e487b7160e01b600052601260045260246000fd5b600061ffff808416806200073e576200073e62000710565b92169190910692915050565b600080600080608085870312156200076157600080fd5b6200076c8562000563565b935060208501518060060b81146200078357600080fd5b604086015190935062000796816200054a565b9150620007a66060860162000620565b905092959194509250565b600082821015620007c657620007c6620006d1565b500390565b600063ffffffff80831681851681830481118215151615620007f157620007f1620006d1565b02949350505050565b600063ffffffff8084168062000814576200081462000710565b92169190910492915050565b6000602082840312156200083357600080fd5b620005f4826200060e565b60805160a05160c05160e05161010051610120516101405161016051611354620008df600039600081816107ef015281816108d701526109170152600061079201526000818161082801526108a50152600050506000818161015c0152818161060401526107150152600081816102660152818161041c01526107bc01526000818160f40152610694015260008181610223015261039601526113546000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063d29d44ee11610066578063d29d44ee14610245578063e38d6b5c14610258578063fdf262b714610261578063feaf968c1461028857600080fd5b80638da5cb5b146101c15780639a6fc8f5146101d4578063cdf456e11461021e57600080fd5b80633c1d5df0116100c85780633c1d5df0146101575780634b3f28891461019357806354fd4d501461019b5780637284e416146101ac57600080fd5b806316f0115b146100ef57806327163d4a14610133578063313ce56714610148575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610146610141366004610d77565b610290565b005b6040516008815260200161012a565b61017e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161012a565b6101466102fb565b60015b60405190815260200161012a565b6101b4610392565b60405161012a9190610dc0565b600054610116906001600160a01b031681565b6101e76101e2366004610df3565b6104c5565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161012a565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610146610253366004610e37565b6104ea565b61019e60015481565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6101e76105b9565b6000546001600160a01b031633146102d55760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044015b60405180910390fd5b600081136102f65760405163119ced2160e21b815260040160405180910390fd5b600155565b6000546001600160a01b0316331461033b5760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044016102cc565b600080546040516001600160a01b03909116907f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60607f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156103f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261041a9190810190610e9b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610478573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104a09190810190610e9b565b6040516020016104b1929190610f2f565b604051602081830303815290604052905090565b6000806000806000856104d66105dd565b909790965060009550859450849350915050565b6000546001600160a01b0316331461052a5760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044016102cc565b6001600160a01b03811661055157604051634208fc5d60e01b815260040160405180910390fd5b600080546040516001600160a01b03808516939216917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c91a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000806000806000806105ca6105dd565b9096909550600094504293508492509050565b604080516002808252606082018352600092839291906020830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061063657610636610f6d565b602002602001019063ffffffff16908163ffffffff168152505060008160018151811061066557610665610f6d565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063883bdbfd906106c9908590600401610f83565b600060405180830381865afa1580156106e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261070e9190810190611065565b50905060007f000000000000000000000000000000000000000000000000000000000000000060030b8260008151811061074a5761074a610f6d565b60200260200101518360018151811061076557610765610f6d565b60200260200101516107779190611147565b61078191906111ad565b9050600061078e82610982565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161415610892576108157f0000000000000000000000000000000000000000000000000000000000000000600a6112d1565b6108816001600160a01b0383168061084e7f000000000000000000000000000000000000000000000000000000000000000060086112e0565b61085990600a6112d1565b61087c907801000000000000000000000000000000000000000000000000611305565b610cc2565b61088b9190611305565b9450610955565b6108cb6001600160a01b0382168061084e7f000000000000000000000000000000000000000000000000000000000000000060086112e0565b945084610911576108fd7f000000000000000000000000000000000000000000000000000000000000000060106112e0565b61090890600a6112d1565b94505050505090565b8461093d7f000000000000000000000000000000000000000000000000000000000000000060106112e0565b61094890600a6112d1565b6109529190611319565b94505b60015485131561096b5760015494505050505090565b8461097b57600194505050505090565b5050505090565b60008060008360020b12610999578260020b6109a1565b8260020b6000035b9050620d89e88111156109da5760405162461bcd60e51b81526020600482015260016024820152601560fa1b60448201526064016102cc565b6000600182166109fb57700100000000000000000000000000000000610a0d565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610a41576ffff97272373d413259a46990580e213a0260801c5b6004821615610a60576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610a7f576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615610a9e576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615610abd576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615610adc576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610afb576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610b1b576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610b3b576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610b5b576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610b7b576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610b9b576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610bbb576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610bdb576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610bfb576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610c1c576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610c3c576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610c5b576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610c78576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610c99578060001981610c9557610c95611197565b0490505b640100000000810615610cad576001610cb0565b60005b60ff16602082901c0192505050919050565b600080806000198587098587029250828110838203039150508060001415610cfc5760008411610cf157600080fd5b508290049050610d70565b808411610d0857600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600060208284031215610d8957600080fd5b5035919050565b60005b83811015610dab578181015183820152602001610d93565b83811115610dba576000848401525b50505050565b6020815260008251806020840152610ddf816040850160208701610d90565b601f01601f19169190910160400192915050565b600060208284031215610e0557600080fd5b813569ffffffffffffffffffff81168114610d7057600080fd5b6001600160a01b0381168114610e3457600080fd5b50565b600060208284031215610e4957600080fd5b8135610d7081610e1f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610e9357610e93610e54565b604052919050565b600060208284031215610ead57600080fd5b815167ffffffffffffffff80821115610ec557600080fd5b818401915084601f830112610ed957600080fd5b815181811115610eeb57610eeb610e54565b610efe601f8201601f1916602001610e6a565b9150808252856020828501011115610f1557600080fd5b610f26816020840160208601610d90565b50949350505050565b60008351610f41818460208801610d90565b6201017960ed1b9083019081528351610f61816003840160208801610d90565b01600301949350505050565b634e487b7160e01b600052603260045260246000fd5b6020808252825182820181905260009190848201906040850190845b81811015610fc157835163ffffffff1683529284019291840191600101610f9f565b50909695505050505050565b600067ffffffffffffffff821115610fe757610fe7610e54565b5060051b60200190565b600082601f83011261100257600080fd5b8151602061101761101283610fcd565b610e6a565b82815260059290921b8401810191818101908684111561103657600080fd5b8286015b8481101561105a57805161104d81610e1f565b835291830191830161103a565b509695505050505050565b6000806040838503121561107857600080fd5b825167ffffffffffffffff8082111561109057600080fd5b818501915085601f8301126110a457600080fd5b815160206110b461101283610fcd565b82815260059290921b840181019181810190898411156110d357600080fd5b948201945b838610156111015785518060060b81146110f25760008081fd5b825294820194908201906110d8565b9188015191965090935050508082111561111a57600080fd5b5061112785828601610ff1565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160060b8360060b6000811281667fffffffffffff190183128115161561117257611172611131565b81667fffffffffffff01831381161561118d5761118d611131565b5090039392505050565b634e487b7160e01b600052601260045260246000fd5b60008160060b8360060b806111c4576111c4611197565b667fffffffffffff198214600019821416156111e2576111e2611131565b90059392505050565b600181815b8085111561122657816000190482111561120c5761120c611131565b8085161561121957918102915b93841c93908002906111f0565b509250929050565b60008261123d575060016112cb565b8161124a575060006112cb565b8160018114611260576002811461126a57611286565b60019150506112cb565b60ff84111561127b5761127b611131565b50506001821b6112cb565b5060208310610133831016604e8410600b84101617156112a9575081810a6112cb565b6112b383836111eb565b80600019048211156112c7576112c7611131565b0290505b92915050565b6000610d7060ff84168361122e565b600060ff821660ff84168060ff038211156112fd576112fd611131565b019392505050565b60008261131457611314611197565b500490565b60008261132857611328611197565b600160ff1b82146000198414161561134257611342611131565b50059056fea164736f6c634300080c000a"; + +type GodModeUniswapV3PriceFeedConstructorParams = + | [signer?: Signer] + | ConstructorParameters; + +const isSuperArgs = ( + xs: GodModeUniswapV3PriceFeedConstructorParams +): xs is ConstructorParameters => xs.length > 1; + +export class GodModeUniswapV3PriceFeed__factory extends ContractFactory { + constructor(...args: GodModeUniswapV3PriceFeedConstructorParams) { + if (isSuperArgs(args)) { + super(...args); + } else { + super(_abi, _bytecode, args[0]); + } + } + + override deploy( + pool_: string, + quoteAsset_: string, + twapInterval_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise { + return super.deploy( + pool_, + quoteAsset_, + twapInterval_, + overrides || {} + ) as Promise; + } + override getDeployTransaction( + pool_: string, + quoteAsset_: string, + twapInterval_: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): TransactionRequest { + return super.getDeployTransaction( + pool_, + quoteAsset_, + twapInterval_, + overrides || {} + ); + } + override attach(address: string): GodModeUniswapV3PriceFeed { + return super.attach(address) as GodModeUniswapV3PriceFeed; + } + override connect(signer: Signer): GodModeUniswapV3PriceFeed__factory { + return super.connect(signer) as GodModeUniswapV3PriceFeed__factory; + } + + static readonly bytecode = _bytecode; + static readonly abi = _abi; + static createInterface(): GodModeUniswapV3PriceFeedInterface { + return new utils.Interface(_abi) as GodModeUniswapV3PriceFeedInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): GodModeUniswapV3PriceFeed { + return new Contract( + address, + _abi, + signerOrProvider + ) as GodModeUniswapV3PriceFeed; + } +} diff --git a/packages/protocol/src/types/factories/contracts/test/index.ts b/packages/protocol/src/types/factories/contracts/test/index.ts index 96a34f79..7054238d 100644 --- a/packages/protocol/src/types/factories/contracts/test/index.ts +++ b/packages/protocol/src/types/factories/contracts/test/index.ts @@ -7,3 +7,4 @@ export { GodModeErc20__factory } from "./GodModeErc20__factory"; export { GodModeFintroller__factory } from "./GodModeFintroller__factory"; export { GodModeHToken__factory } from "./GodModeHToken__factory"; export { GodModeOwnableUpgradeable__factory } from "./GodModeOwnableUpgradeable__factory"; +export { GodModeUniswapV3PriceFeed__factory } from "./GodModeUniswapV3PriceFeed__factory"; diff --git a/packages/protocol/src/types/hardhat.d.ts b/packages/protocol/src/types/hardhat.d.ts index 3698a629..95790329 100644 --- a/packages/protocol/src/types/hardhat.d.ts +++ b/packages/protocol/src/types/hardhat.d.ts @@ -88,6 +88,10 @@ declare module "hardhat/types/runtime" { name: "IAggregatorV3", signerOrOptions?: ethers.Signer | FactoryOptions ): Promise; + getContractFactory( + name: "IUniswapV3Pool", + signerOrOptions?: ethers.Signer | FactoryOptions + ): Promise; getContractFactory( name: "ChainlinkOperator", signerOrOptions?: ethers.Signer | FactoryOptions @@ -96,6 +100,10 @@ declare module "hardhat/types/runtime" { name: "IChainlinkOperator", signerOrOptions?: ethers.Signer | FactoryOptions ): Promise; + getContractFactory( + name: "IUniswapV3PriceFeed", + signerOrOptions?: ethers.Signer | FactoryOptions + ): Promise; getContractFactory( name: "SimplePriceFeed", signerOrOptions?: ethers.Signer | FactoryOptions @@ -104,6 +112,10 @@ declare module "hardhat/types/runtime" { name: "StablecoinPriceFeed", signerOrOptions?: ethers.Signer | FactoryOptions ): Promise; + getContractFactory( + name: "UniswapV3PriceFeed", + signerOrOptions?: ethers.Signer | FactoryOptions + ): Promise; getContractFactory( name: "BalanceSheetUpgraded", signerOrOptions?: ethers.Signer | FactoryOptions @@ -136,6 +148,10 @@ declare module "hardhat/types/runtime" { name: "GodModeOwnableUpgradeable", signerOrOptions?: ethers.Signer | FactoryOptions ): Promise; + getContractFactory( + name: "GodModeUniswapV3PriceFeed", + signerOrOptions?: ethers.Signer | FactoryOptions + ): Promise; getContractAt( name: "IOwnable", @@ -232,6 +248,11 @@ declare module "hardhat/types/runtime" { address: string, signer?: ethers.Signer ): Promise; + getContractAt( + name: "IUniswapV3Pool", + address: string, + signer?: ethers.Signer + ): Promise; getContractAt( name: "ChainlinkOperator", address: string, @@ -242,6 +263,11 @@ declare module "hardhat/types/runtime" { address: string, signer?: ethers.Signer ): Promise; + getContractAt( + name: "IUniswapV3PriceFeed", + address: string, + signer?: ethers.Signer + ): Promise; getContractAt( name: "SimplePriceFeed", address: string, @@ -252,6 +278,11 @@ declare module "hardhat/types/runtime" { address: string, signer?: ethers.Signer ): Promise; + getContractAt( + name: "UniswapV3PriceFeed", + address: string, + signer?: ethers.Signer + ): Promise; getContractAt( name: "BalanceSheetUpgraded", address: string, @@ -292,6 +323,11 @@ declare module "hardhat/types/runtime" { address: string, signer?: ethers.Signer ): Promise; + getContractAt( + name: "GodModeUniswapV3PriceFeed", + address: string, + signer?: ethers.Signer + ): Promise; // default types getContractFactory( diff --git a/packages/protocol/src/types/index.ts b/packages/protocol/src/types/index.ts index ddad0a71..a82e3804 100644 --- a/packages/protocol/src/types/index.ts +++ b/packages/protocol/src/types/index.ts @@ -48,14 +48,20 @@ export type { IHToken } from "./contracts/core/h-token/IHToken"; export { IHToken__factory } from "./factories/contracts/core/h-token/IHToken__factory"; export type { IAggregatorV3 } from "./contracts/external/chainlink/IAggregatorV3"; export { IAggregatorV3__factory } from "./factories/contracts/external/chainlink/IAggregatorV3__factory"; +export type { IUniswapV3Pool } from "./contracts/external/uniswap/interfaces/IUniswapV3Pool"; +export { IUniswapV3Pool__factory } from "./factories/contracts/external/uniswap/interfaces/IUniswapV3Pool__factory"; export type { ChainlinkOperator } from "./contracts/oracles/ChainlinkOperator"; export { ChainlinkOperator__factory } from "./factories/contracts/oracles/ChainlinkOperator__factory"; export type { IChainlinkOperator } from "./contracts/oracles/IChainlinkOperator"; export { IChainlinkOperator__factory } from "./factories/contracts/oracles/IChainlinkOperator__factory"; +export type { IUniswapV3PriceFeed } from "./contracts/oracles/IUniswapV3PriceFeed"; +export { IUniswapV3PriceFeed__factory } from "./factories/contracts/oracles/IUniswapV3PriceFeed__factory"; export type { SimplePriceFeed } from "./contracts/oracles/SimplePriceFeed"; export { SimplePriceFeed__factory } from "./factories/contracts/oracles/SimplePriceFeed__factory"; export type { StablecoinPriceFeed } from "./contracts/oracles/StablecoinPriceFeed"; export { StablecoinPriceFeed__factory } from "./factories/contracts/oracles/StablecoinPriceFeed__factory"; +export type { UniswapV3PriceFeed } from "./contracts/oracles/UniswapV3PriceFeed"; +export { UniswapV3PriceFeed__factory } from "./factories/contracts/oracles/UniswapV3PriceFeed__factory"; export type { BalanceSheetUpgraded } from "./contracts/test/BalanceSheetUpgraded.sol/BalanceSheetUpgraded"; export { BalanceSheetUpgraded__factory } from "./factories/contracts/test/BalanceSheetUpgraded.sol/BalanceSheetUpgraded__factory"; export type { IBalanceSheetUpgraded } from "./contracts/test/BalanceSheetUpgraded.sol/IBalanceSheetUpgraded"; @@ -72,3 +78,5 @@ export type { GodModeHToken } from "./contracts/test/GodModeHToken"; export { GodModeHToken__factory } from "./factories/contracts/test/GodModeHToken__factory"; export type { GodModeOwnableUpgradeable } from "./contracts/test/GodModeOwnableUpgradeable"; export { GodModeOwnableUpgradeable__factory } from "./factories/contracts/test/GodModeOwnableUpgradeable__factory"; +export type { GodModeUniswapV3PriceFeed } from "./contracts/test/GodModeUniswapV3PriceFeed"; +export { GodModeUniswapV3PriceFeed__factory } from "./factories/contracts/test/GodModeUniswapV3PriceFeed__factory"; diff --git a/packages/protocol/tasks/constants.ts b/packages/protocol/tasks/constants.ts index 660bcacb..eeb37014 100644 --- a/packages/protocol/tasks/constants.ts +++ b/packages/protocol/tasks/constants.ts @@ -4,5 +4,6 @@ export const TASK_DEPLOY_CONTRACT_FINTROLLER: string = "deploy:contract:fintroll export const TASK_DEPLOY_CONTRACT_H_TOKEN: string = "deploy:contract:h-token"; export const TASK_DEPLOY_CONTRACT_SIMPLE_PRICE_FEED: string = "deploy:contract:simple-price-feed"; export const TASK_DEPLOY_CONTRACT_STABLECOIN_PRICE_FEED: string = "deploy:contract:stablecoin-price-feed"; +export const TASK_DEPLOY_CONTRACT_UNISWAP_V3_PRICE_FEED: string = "deploy:contract:uniswap-v3-price-feed"; export const TASK_PREPARE_UPGRADE_BALANCE_SHEET: string = "prepare:upgrade:balance-sheet"; export const SUBTASK_DEPLOY_WAIT_FOR_CONFIRMATIONS: string = "deploy:wait-for-confirmations"; diff --git a/packages/protocol/tasks/deploy/index.ts b/packages/protocol/tasks/deploy/index.ts index 152234c7..a256e4f1 100644 --- a/packages/protocol/tasks/deploy/index.ts +++ b/packages/protocol/tasks/deploy/index.ts @@ -4,4 +4,5 @@ import "./fintroller"; import "./hToken"; import "./simplePriceFeed"; import "./stablecoinPriceFeed"; +import "./uniswapV3PriceFeed"; import "./waitForConfirmations"; diff --git a/packages/protocol/tasks/deploy/uniswapV3PriceFeed.ts b/packages/protocol/tasks/deploy/uniswapV3PriceFeed.ts new file mode 100644 index 00000000..6856c262 --- /dev/null +++ b/packages/protocol/tasks/deploy/uniswapV3PriceFeed.ts @@ -0,0 +1,52 @@ +import type { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { task, types } from "hardhat/config"; +import type { TaskArguments } from "hardhat/types"; + +import type { UniswapV3PriceFeed } from "../../src/types/contracts/oracles/UniswapV3PriceFeed"; +import { UniswapV3PriceFeed__factory } from "../../src/types/factories/contracts/oracles/UniswapV3PriceFeed__factory"; +import { SUBTASK_DEPLOY_WAIT_FOR_CONFIRMATIONS, TASK_DEPLOY_CONTRACT_UNISWAP_V3_PRICE_FEED } from "../constants"; + +task(TASK_DEPLOY_CONTRACT_UNISWAP_V3_PRICE_FEED) + // Contract arguments + .addParam("pool", "Address of the Uniswap V3 pool") + .addParam("quoteAsset", "Address of the quote asset for price calculation") + .addParam("twapInterval", "The time interval for TWAP calculation") + .addParam("maxPrice", "The maximum price for the price feed") + // Developer settings + .addOptionalParam("confirmations", "How many block confirmations to wait for", 2, types.int) + .addOptionalParam("print", "Print the address in the console", true, types.boolean) + .addOptionalParam("verify", "Verify the contract on Etherscan", true, types.boolean) + .setAction(async function (taskArgs: TaskArguments, { ethers, run }): Promise { + const signers: SignerWithAddress[] = await ethers.getSigners(); + const uniswapV3PriceFeedFactory: UniswapV3PriceFeed__factory = new UniswapV3PriceFeed__factory(signers[0]); + const uniswapV3PriceFeed: UniswapV3PriceFeed = ( + await uniswapV3PriceFeedFactory.deploy( + taskArgs.pool, + taskArgs.quoteAsset, + taskArgs.twapInterval, + taskArgs.maxPrice, + ) + ); + + await run(SUBTASK_DEPLOY_WAIT_FOR_CONFIRMATIONS, { + contract: uniswapV3PriceFeed, + confirmations: taskArgs.confirmations, + }); + + if (taskArgs.print) { + console.table([{ name: "UniswapV3PriceFeed", address: uniswapV3PriceFeed.address }]); + } + + if (taskArgs.verify) { + try { + await run("verify:verify", { + address: uniswapV3PriceFeed.address, + constructorArguments: [taskArgs.pool, taskArgs.quoteAsset, taskArgs.twapInterval, taskArgs.maxPrice], + }); + } catch (error) { + console.error("Error while verifying contract:", error); + } + } + + return uniswapV3PriceFeed.address; + }); diff --git a/packages/protocol/test/shared/deployers.ts b/packages/protocol/test/shared/deployers.ts index 2b301213..66c1128d 100644 --- a/packages/protocol/test/shared/deployers.ts +++ b/packages/protocol/test/shared/deployers.ts @@ -22,6 +22,7 @@ import type { GodModeErc20 } from "../../src/types/contracts/test/GodModeErc20"; import type { GodModeFintroller } from "../../src/types/contracts/test/GodModeFintroller"; import type { GodModeHToken } from "../../src/types/contracts/test/GodModeHToken"; import type { GodModeOwnableUpgradeable } from "../../src/types/contracts/test/GodModeOwnableUpgradeable"; +import type { GodModeUniswapV3PriceFeed } from "../../src/types/contracts/test/GodModeUniswapV3PriceFeed"; import type { GodModeBalanceSheet__factory } from "../../src/types/factories/contracts/test/GodModeBalanceSheet__factory"; import type { GodModeOwnableUpgradeable__factory } from "../../src/types/factories/contracts/test/GodModeOwnableUpgradeable__factory"; @@ -119,6 +120,24 @@ export async function deployOwnableUpgradeable(): Promise { + const uniswapV3PriceFeedArtifact: Artifact = await artifacts.readArtifact("GodModeUniswapV3PriceFeed"); + const priceFeed: GodModeUniswapV3PriceFeed = ( + await deployContract( + deployer, + uniswapV3PriceFeedArtifact, + [poolAddress, quoteAssetAddress, twapInterval], + overrides, + ) + ); + return priceFeed; +} + export async function deployUsdc(deployer: Signer): Promise { const godModeErc20Artifact: Artifact = await artifacts.readArtifact("GodModeErc20"); const usdc: GodModeErc20 = ( diff --git a/packages/protocol/test/shared/fixtures.ts b/packages/protocol/test/shared/fixtures.ts index 6c05a051..58677c4b 100644 --- a/packages/protocol/test/shared/fixtures.ts +++ b/packages/protocol/test/shared/fixtures.ts @@ -1,5 +1,7 @@ import type { Signer } from "@ethersproject/abstract-signer"; import { + DEFAULT_CARDINALITY, + DEFAULT_TWAP_INTERVAL, H_TOKEN_MATURITY_ONE_YEAR, H_TOKEN_MATURITY_THREE_MONTHS, NORMALIZED_USDC_PRICE, @@ -12,6 +14,7 @@ import { WETH_SYMBOL, } from "@hifi/constants"; import type { MockContract } from "ethereum-waffle"; +import { ethers } from "hardhat"; import type { ChainlinkOperator } from "../../src/types/contracts/oracles/ChainlinkOperator"; import type { SimplePriceFeed } from "../../src/types/contracts/oracles/SimplePriceFeed"; @@ -20,12 +23,14 @@ import type { GodModeErc20 } from "../../src/types/contracts/test/GodModeErc20"; import { GodModeFintroller } from "../../src/types/contracts/test/GodModeFintroller"; import type { GodModeHToken } from "../../src/types/contracts/test/GodModeHToken"; import type { GodModeOwnableUpgradeable } from "../../src/types/contracts/test/GodModeOwnableUpgradeable"; +import type { GodModeUniswapV3PriceFeed } from "../../src/types/contracts/test/GodModeUniswapV3PriceFeed"; import { deployChainlinkOperator, deployGodModeBalanceSheet, deployGodModeFintroller, deployGodModeHToken, deployOwnableUpgradeable, + deployUniswapV3PriceFeed, deployUsdc, deployUsdcPriceFeed, deployWbtc, @@ -37,6 +42,7 @@ import { deployMockFintroller, deployMockHToken, deployMockSimplePriceFeed, + deployMockUniswapV3Pool, deployMockUsdc, deployMockWbtc, deployMockWeth, @@ -197,3 +203,37 @@ export async function unitFixtureOwnableUpgradeable(): Promise { + const deployer: Signer = signers[0]; + + const pool: MockContract = await deployMockUniswapV3Pool(deployer); + const usdc: MockContract = await deployMockUsdc(deployer); + const wbtc: MockContract = await deployMockWbtc(deployer); + await pool.mock.token0.returns(usdc.address); + await pool.mock.token1.returns(wbtc.address); + + const currentIndex: number = 0; + await pool.mock.slot0.returns(0, 0, currentIndex, DEFAULT_CARDINALITY, DEFAULT_CARDINALITY, 0, 0); + + const oldestIndex: number = (currentIndex + 1) % DEFAULT_CARDINALITY; + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + const oldestAvailableAge: number = timestamp - DEFAULT_TWAP_INTERVAL; + const initialized: boolean = true; + await pool.mock.observations.withArgs(oldestIndex).returns(oldestAvailableAge, 0, 0, initialized); + + const priceFeed: GodModeUniswapV3PriceFeed = await deployUniswapV3PriceFeed( + deployer, + pool.address, + usdc.address, + DEFAULT_TWAP_INTERVAL, + ); + return { pool, priceFeed, usdc, wbtc }; +} diff --git a/packages/protocol/test/shared/mirrors.ts b/packages/protocol/test/shared/mirrors.ts index fc2528de..ee213501 100644 --- a/packages/protocol/test/shared/mirrors.ts +++ b/packages/protocol/test/shared/mirrors.ts @@ -6,11 +6,13 @@ import { NORMALIZED_USDC_PRICE, NORMALIZED_WBTC_PRICE, NORMALIZED_WETH_PRICE, + Q192, WBTC_DECIMALS, WBTC_PRICE_PRECISION_SCALAR, } from "@hifi/constants"; import { getPrecisionScalar } from "@hifi/helpers"; import { div, mul } from "@prb/math"; +import { TickMath } from "@uniswap/v3-sdk"; export function getHypotheticalAccountLiquidity( collateralAmounts: BigNumber[], @@ -83,3 +85,23 @@ export function weighWeth( ): BigNumber { return div(mul(wethDepositAmount, NORMALIZED_WETH_PRICE), collateralRatio); } + +export function calculateTick(tickCumulatives: number[], twapInterval: number): number { + const tick = BigNumber.from(tickCumulatives[1]) + .sub(BigNumber.from(tickCumulatives[0])) + .div(BigNumber.from(twapInterval)) + .toNumber(); + return tick; +} + +export function tickToTokenPrices(tick: number, token0Decimals: number, token1Decimals: number): BigNumber[] { + const sqrtPriceX96: BigNumber = BigNumber.from(TickMath.getSqrtRatioAtTick(tick).toString()); + const num: BigNumber = sqrtPriceX96.mul(sqrtPriceX96); + const denom: BigNumber = Q192.div(BigNumber.from("10").pow(BigNumber.from(token0Decimals).add(8))); + const base: BigNumber = num.div(denom); + const price0: BigNumber = base.eq(0) + ? BigNumber.from("10").pow(BigNumber.from(token1Decimals).add(16)) + : BigNumber.from("10").pow(BigNumber.from(token1Decimals).add(16)).div(base); + const price1: BigNumber = base.div(BigNumber.from("10").pow(BigNumber.from(token1Decimals))); + return [price0.eq(0) ? BigNumber.from("1") : price0, price1.eq(0) ? BigNumber.from("1") : price1]; +} diff --git a/packages/protocol/test/shared/mocks.ts b/packages/protocol/test/shared/mocks.ts index 51147404..7571a9e6 100644 --- a/packages/protocol/test/shared/mocks.ts +++ b/packages/protocol/test/shared/mocks.ts @@ -72,6 +72,12 @@ export async function deployMockSimplePriceFeed(deployer: Signer, price: BigNumb return simplePriceFeed; } +export async function deployMockUniswapV3Pool(deployer: Signer): Promise { + const uniswapV3PoolArtifact: Artifact = await hre.artifacts.readArtifact("IUniswapV3Pool"); + const uniswapV3Pool: MockContract = await deployMockContract(deployer, uniswapV3PoolArtifact.abi); + return uniswapV3Pool; +} + export async function deployMockUsdc(deployer: Signer): Promise { return deployMockErc20(deployer, USDC_NAME, USDC_SYMBOL, USDC_DECIMALS); } diff --git a/packages/protocol/test/shared/types.ts b/packages/protocol/test/shared/types.ts index 25ce483c..9ce021bb 100644 --- a/packages/protocol/test/shared/types.ts +++ b/packages/protocol/test/shared/types.ts @@ -9,6 +9,7 @@ import type { GodModeErc20 } from "../../src/types/contracts/test/GodModeErc20"; import type { GodModeFintroller } from "../../src/types/contracts/test/GodModeFintroller"; import type { GodModeHToken } from "../../src/types/contracts/test/GodModeHToken"; import type { GodModeOwnableUpgradeable } from "../../src/types/contracts/test/GodModeOwnableUpgradeable"; +import type { GodModeUniswapV3PriceFeed } from "../../src/types/contracts/test/GodModeUniswapV3PriceFeed"; declare module "mocha" { interface Context { @@ -25,6 +26,7 @@ export interface Contracts { hTokens: GodModeHToken[]; oracle: ChainlinkOperator; ownableUpgradeable: GodModeOwnableUpgradeable; + uniswapV3priceFeed: GodModeUniswapV3PriceFeed; usdc: GodModeErc20; usdcPriceFeed: SimplePriceFeed; wbtc: GodModeErc20; @@ -36,6 +38,7 @@ export interface Mocks { fintroller: MockContract; hTokens: MockContract[]; oracle: MockContract; + pool: MockContract; usdc: MockContract; usdcPriceFeed: MockContract; wbtc: MockContract; diff --git a/packages/protocol/test/unit/index.ts b/packages/protocol/test/unit/index.ts index 37442f48..86abd785 100644 --- a/packages/protocol/test/unit/index.ts +++ b/packages/protocol/test/unit/index.ts @@ -3,6 +3,7 @@ import { unitTestBalanceSheet } from "./balance-sheet/BalanceSheet"; import { unitTestChainlinkOperator } from "./chainlink-operator/ChainlinkOperator"; import { unitTestFintroller } from "./fintroller/Fintroller"; import { unitTestHToken } from "./h-token/HToken"; +import { unitTestUniswapV3PriceFeed } from "./oracles/uniswap-v3-price-feed/UniswapV3PriceFeed"; import { unitTestOwnableUpgradeable } from "./ownable-upgradeable/OwnableUpgradeable"; baseContext("Unit Tests", function () { @@ -10,5 +11,6 @@ baseContext("Unit Tests", function () { unitTestChainlinkOperator(); unitTestFintroller(); unitTestHToken(); + unitTestUniswapV3PriceFeed(); unitTestOwnableUpgradeable(); }); diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/UniswapV3PriceFeed.behavior.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/UniswapV3PriceFeed.behavior.ts new file mode 100644 index 00000000..fe62ec9f --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/UniswapV3PriceFeed.behavior.ts @@ -0,0 +1,68 @@ +import { shouldBehaveLikeConstructor } from "./deployment/constructor"; +import { shouldBehaveLikeSetMaxPrice } from "./effects/setMaxPrice"; +import { shouldBehaveLikeBaseAsset } from "./view/baseAsset"; +import { shouldBehaveLikeDecimals } from "./view/decimals"; +import { shouldBehaveLikeDescription } from "./view/description"; +import { shouldBehaveLikeGetRoundData } from "./view/getRoundData"; +import { shouldBehaveLikeLatestRoundData } from "./view/latestRoundData"; +import { shouldBehaveLikeMaxPrice } from "./view/maxPrice"; +import { shouldBehaveLikePool } from "./view/pool"; +import { shouldBehaveLikeQuoteAsset } from "./view/quoteAsset"; +import { shouldBehaveLikeTwapInterval } from "./view/twapInterval"; +import { shouldBehaveLikeVersion } from "./view/version"; + +export function shouldBehaveLikeUniswapV3PriceFeed(): void { + describe("Deployment", function () { + describe("constructor", function () { + shouldBehaveLikeConstructor(); + }); + }); + + describe("View Functions", function () { + describe("baseAsset", function () { + shouldBehaveLikeBaseAsset(); + }); + + describe("description", function () { + shouldBehaveLikeDescription(); + }); + + describe("maxPrice", function () { + shouldBehaveLikeMaxPrice(); + }); + + describe("pool", function () { + shouldBehaveLikePool(); + }); + + describe("quoteAsset", function () { + shouldBehaveLikeQuoteAsset(); + }); + + describe("twapInterval", function () { + shouldBehaveLikeTwapInterval(); + }); + + describe("decimals", function () { + shouldBehaveLikeDecimals(); + }); + + describe("version", function () { + shouldBehaveLikeVersion(); + }); + + describe("getRoundData", function () { + shouldBehaveLikeGetRoundData(); + }); + + describe("latestRoundData", function () { + shouldBehaveLikeLatestRoundData(); + }); + }); + + describe("Effects Functions", function () { + describe("setMaxPrice", function () { + shouldBehaveLikeSetMaxPrice(); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/UniswapV3PriceFeed.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/UniswapV3PriceFeed.ts new file mode 100644 index 00000000..049dbfad --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/UniswapV3PriceFeed.ts @@ -0,0 +1,16 @@ +import { unitFixtureUniswapV3PriceFeed } from "../../../shared/fixtures"; +import { shouldBehaveLikeUniswapV3PriceFeed } from "./UniswapV3PriceFeed.behavior"; + +export function unitTestUniswapV3PriceFeed(): void { + describe("UniswapV3PriceFeed", function () { + beforeEach(async function () { + const { pool, priceFeed, usdc, wbtc } = await this.loadFixture(unitFixtureUniswapV3PriceFeed); + this.mocks.pool = pool; + this.mocks.usdc = usdc; + this.mocks.wbtc = wbtc; + this.contracts.uniswapV3priceFeed = priceFeed; + }); + + shouldBehaveLikeUniswapV3PriceFeed(); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/deployment/constructor.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/deployment/constructor.ts new file mode 100644 index 00000000..c87a3ee8 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/deployment/constructor.ts @@ -0,0 +1,179 @@ +import { DEFAULT_CARDINALITY, DEFAULT_TWAP_INTERVAL } from "@hifi/constants"; +import { UniswapV3PriceFeedErrors } from "@hifi/errors"; +import { expect } from "chai"; +import { MockContract } from "ethereum-waffle"; +import { Signer } from "ethers"; +import { ethers } from "hardhat"; + +import type { GodModeUniswapV3PriceFeed } from "../../../../../src/types/contracts/test/GodModeUniswapV3PriceFeed"; +import { deployUniswapV3PriceFeed } from "../../../../shared/deployers"; +import { deployMockUniswapV3Pool, deployMockUsdc, deployMockWbtc, deployMockWeth } from "../../../../shared/mocks"; + +export function shouldBehaveLikeConstructor(): void { + let deployer: Signer; + let pool: MockContract; + let usdc: MockContract; + let weth: MockContract; + + beforeEach(async function () { + deployer = this.signers.admin; + pool = await deployMockUniswapV3Pool(deployer); + usdc = await deployMockUsdc(deployer); + weth = await deployMockWeth(deployer); + }); + + context("when the quote asset is not in the provided pool", function () { + let wbtc: MockContract; + + beforeEach(async function () { + wbtc = await deployMockWbtc(deployer); + await pool.mock.token0.returns(usdc.address); + await pool.mock.token1.returns(wbtc.address); + }); + + it("reverts", async function () { + const deployUniswapV3PriceFeedPromise: Promise = deployUniswapV3PriceFeed( + deployer, + pool.address, + weth.address, + DEFAULT_TWAP_INTERVAL, + ); + + await expect(deployUniswapV3PriceFeedPromise).to.be.revertedWith( + UniswapV3PriceFeedErrors.QUOTE_ASSET_NOT_IN_POOL, + ); + }); + }); + + context("when the quote asset is in the provided pool", function () { + let oldestAvailableAge: number; + let latestObservationIsInitialized: boolean; + + beforeEach(async function () { + await pool.mock.token0.returns(usdc.address); + await pool.mock.token1.returns(weth.address); + }); + + context("when the next observation in ring buffer has not been initialized", function () { + context("when the pool does not have enough TWAP available", function () { + beforeEach(async function () { + const currentIndex: number = 0; + await pool.mock.slot0.returns(0, 0, currentIndex, DEFAULT_CARDINALITY, 0, 0, 0); + + const oldestIndex: number = (currentIndex + 1) % DEFAULT_CARDINALITY; + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + oldestAvailableAge = timestamp - DEFAULT_TWAP_INTERVAL + 60; + latestObservationIsInitialized = false; + await pool.mock.observations + .withArgs(oldestIndex) + .returns(oldestAvailableAge, 0, 0, latestObservationIsInitialized); + const zeroObservationIsInitialized: boolean = true; + await pool.mock.observations.withArgs(0).returns(oldestAvailableAge, 0, 0, zeroObservationIsInitialized); + }); + + it("reverts", async function () { + const deployUniswapV3PriceFeedPromise: Promise = deployUniswapV3PriceFeed( + deployer, + pool.address, + usdc.address, + DEFAULT_TWAP_INTERVAL, + ); + + await expect(deployUniswapV3PriceFeedPromise).to.be.revertedWith( + UniswapV3PriceFeedErrors.TWAP_CRITERIA_NOT_SATISFIED, + ); + }); + }); + + context("when the pool has enough TWAP available", function () { + context("when the pool does not have enough cardinality", function () { + beforeEach(async function () { + const currentIndex: number = 0; + await pool.mock.slot0.returns(0, 0, currentIndex, DEFAULT_CARDINALITY - 1, 0, 0, 0); + + const oldestIndex: number = (currentIndex + 1) % (DEFAULT_CARDINALITY - 1); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + const oldestAvailableAge: number = timestamp - DEFAULT_TWAP_INTERVAL; + const latestObservationIsInitialized: boolean = false; + await pool.mock.observations + .withArgs(oldestIndex) + .returns(oldestAvailableAge, 0, 0, latestObservationIsInitialized); + const zeroObservationIsInitialized: boolean = true; + await pool.mock.observations.withArgs(0).returns(oldestAvailableAge, 0, 0, zeroObservationIsInitialized); + }); + + it("reverts", async function () { + const deployUniswapV3PriceFeedPromise: Promise = deployUniswapV3PriceFeed( + deployer, + pool.address, + usdc.address, + DEFAULT_TWAP_INTERVAL, + ); + + await expect(deployUniswapV3PriceFeedPromise).to.be.revertedWith( + UniswapV3PriceFeedErrors.TWAP_CRITERIA_NOT_SATISFIED, + ); + }); + }); + }); + }); + + context("when the next observation in ring buffer has been initialized", function () { + context("when the pool does not have enough TWAP available", function () { + beforeEach(async function () { + const currentIndex: number = 0; + await pool.mock.slot0.returns(0, 0, currentIndex, DEFAULT_CARDINALITY, 0, 0, 0); + + const oldestIndex: number = (currentIndex + 1) % DEFAULT_CARDINALITY; + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + const oldestAvailableAge: number = timestamp - DEFAULT_TWAP_INTERVAL + 60; + const latestObservationIsInitialized: boolean = true; + await pool.mock.observations + .withArgs(oldestIndex) + .returns(oldestAvailableAge, 0, 0, latestObservationIsInitialized); + }); + + it("reverts", async function () { + const deployUniswapV3PriceFeedPromise: Promise = deployUniswapV3PriceFeed( + deployer, + pool.address, + usdc.address, + DEFAULT_TWAP_INTERVAL, + ); + + await expect(deployUniswapV3PriceFeedPromise).to.be.revertedWith( + UniswapV3PriceFeedErrors.TWAP_CRITERIA_NOT_SATISFIED, + ); + }); + }); + + context("when the pool does not have enough cardinality", function () { + beforeEach(async function () { + const currentIndex: number = 0; + await pool.mock.slot0.returns(0, 0, currentIndex, DEFAULT_CARDINALITY - 1, 0, 0, 0); + + const oldestIndex: number = (currentIndex + 1) % (DEFAULT_CARDINALITY - 1); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + const oldestAvailableAge: number = timestamp - DEFAULT_TWAP_INTERVAL; + const latestObservationIsInitialized: boolean = true; + await pool.mock.observations + .withArgs(oldestIndex) + .returns(oldestAvailableAge, 0, 0, latestObservationIsInitialized); + }); + + it("reverts", async function () { + const deployUniswapV3PriceFeedPromise: Promise = deployUniswapV3PriceFeed( + deployer, + pool.address, + usdc.address, + DEFAULT_TWAP_INTERVAL, + ); + + await expect(deployUniswapV3PriceFeedPromise).to.be.revertedWith( + UniswapV3PriceFeedErrors.TWAP_CRITERIA_NOT_SATISFIED, + ); + }); + }); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/effects/setMaxPrice.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/effects/setMaxPrice.ts new file mode 100644 index 00000000..6ce73788 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/effects/setMaxPrice.ts @@ -0,0 +1,29 @@ +import { MinInt256 } from "@ethersproject/constants"; +import { UniswapV3PriceFeedErrors } from "@hifi/errors"; +import { expect } from "chai"; + +export function shouldBehaveLikeSetMaxPrice(): void { + context("when max price is zero", function () { + it("reverts", async function () { + await expect(this.contracts.uniswapV3priceFeed.connect(this.signers.admin).setMaxPrice(0)).to.be.revertedWith( + UniswapV3PriceFeedErrors.MAX_PRICE_LESS_THAN_OR_EQUAL_TO_ZERO, + ); + }); + }); + + context("when max price is negative", function () { + it("reverts", async function () { + await expect( + this.contracts.uniswapV3priceFeed.connect(this.signers.admin).setMaxPrice(MinInt256), + ).to.be.revertedWith(UniswapV3PriceFeedErrors.MAX_PRICE_LESS_THAN_OR_EQUAL_TO_ZERO); + }); + }); + + context("when the max price is greater than zero", function () { + it("sets the max price of the price feed", async function () { + await this.contracts.uniswapV3priceFeed.connect(this.signers.admin).setMaxPrice(1); + const maxPrice = await this.contracts.uniswapV3priceFeed.maxPrice(); + expect(maxPrice).to.equal(1); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/baseAsset.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/baseAsset.ts new file mode 100644 index 00000000..cdc5ed83 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/baseAsset.ts @@ -0,0 +1,8 @@ +import { expect } from "chai"; + +export function shouldBehaveLikeBaseAsset(): void { + it("returns the base asset of the price feed", async function () { + const baseAsset = await this.contracts.uniswapV3priceFeed.baseAsset(); + expect(baseAsset).to.equal(await this.mocks.pool.token1()); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/decimals.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/decimals.ts new file mode 100644 index 00000000..bd049c81 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/decimals.ts @@ -0,0 +1,8 @@ +import { expect } from "chai"; + +export function shouldBehaveLikeDecimals(): void { + it("returns the price feed decimals", async function () { + const decimals = await this.contracts.uniswapV3priceFeed.decimals(); + expect(decimals).to.equal(8); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/description.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/description.ts new file mode 100644 index 00000000..0e7a8750 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/description.ts @@ -0,0 +1,32 @@ +import { USDC_SYMBOL, WBTC_SYMBOL } from "@hifi/constants"; +import { expect } from "chai"; + +export function shouldBehaveLikeDescription(): void { + context("when token0 is the quote asset of the price feed", function () { + beforeEach(async function () { + await this.mocks.pool.mock.token0.returns(this.mocks.usdc.address); + await this.mocks.pool.mock.token1.returns(this.mocks.wbtc.address); + await this.contracts.uniswapV3priceFeed.__godMode_setPool(this.mocks.pool.address); + await this.contracts.uniswapV3priceFeed.__godMode_setQuoteAsset(this.mocks.usdc.address); + }); + + it("returns the description of the price feed", async function () { + const description = await this.contracts.uniswapV3priceFeed.description(); + expect(description).to.equal(WBTC_SYMBOL + " / " + USDC_SYMBOL); + }); + }); + + context("when token1 is the quote asset of the price feed", function () { + beforeEach(async function () { + await this.mocks.pool.mock.token0.returns(this.mocks.usdc.address); + await this.mocks.pool.mock.token1.returns(this.mocks.wbtc.address); + await this.contracts.uniswapV3priceFeed.__godMode_setPool(this.mocks.pool.address); + await this.contracts.uniswapV3priceFeed.__godMode_setQuoteAsset(this.mocks.wbtc.address); + }); + + it("returns the description of the price feed", async function () { + const description = await this.contracts.uniswapV3priceFeed.description(); + expect(description).to.equal(USDC_SYMBOL + " / " + WBTC_SYMBOL); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/getRoundData.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/getRoundData.ts new file mode 100644 index 00000000..4ffc0ada --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/getRoundData.ts @@ -0,0 +1,130 @@ +import { DEFAULT_TWAP_INTERVAL, TICKS } from "@hifi/constants"; +import { expect } from "chai"; + +import { calculateTick, tickToTokenPrices } from "../../../../shared/mirrors"; + +export function shouldBehaveLikeGetRoundData(): void { + context("when token0 is the quote asset of the price feed", function () { + let token0Decimals: number; + let token1Decimals: number; + + beforeEach(async function () { + await this.mocks.pool.mock.token0.returns(this.mocks.usdc.address); + await this.mocks.pool.mock.token1.returns(this.mocks.wbtc.address); + await this.contracts.uniswapV3priceFeed.__godMode_setPool(this.mocks.pool.address); + await this.contracts.uniswapV3priceFeed.__godMode_setQuoteAsset(this.mocks.usdc.address); + token0Decimals = await this.mocks.usdc.decimals(); + token1Decimals = await this.mocks.wbtc.decimals(); + }); + + context("when sqrtPriceX96 is minimum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.lowerBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.getRoundData(123); + expect(roundId).to.equal(123); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[0]); + expect(startedAt).to.equal(0); + expect(updatedAt).to.equal(0); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is maximum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.upperBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.getRoundData(123); + expect(roundId).to.equal(123); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[0]); + expect(startedAt).to.equal(0); + expect(updatedAt).to.equal(0); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is above minimum and below maximum", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [3541, 496]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.getRoundData(123); + expect(roundId).to.equal(123); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[0]); + expect(startedAt).to.equal(0); + expect(updatedAt).to.equal(0); + expect(answeredInRound).to.equal(0); + }); + }); + }); + + context("when token1 is the quote asset of the price feed", function () { + let token0Decimals: number; + let token1Decimals: number; + + beforeEach(async function () { + await this.mocks.pool.mock.token0.returns(this.mocks.wbtc.address); + await this.mocks.pool.mock.token1.returns(this.mocks.usdc.address); + await this.contracts.uniswapV3priceFeed.__godMode_setPool(this.mocks.pool.address); + await this.contracts.uniswapV3priceFeed.__godMode_setQuoteAsset(this.mocks.usdc.address); + token0Decimals = await this.mocks.wbtc.decimals(); + token1Decimals = await this.mocks.usdc.decimals(); + }); + + context("when sqrtPriceX96 is minimum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.lowerBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.getRoundData(123); + expect(roundId).to.equal(123); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[1]); + expect(startedAt).to.equal(0); + expect(updatedAt).to.equal(0); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is maximum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.upperBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.getRoundData(123); + expect(roundId).to.equal(123); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[1]); + expect(startedAt).to.equal(0); + expect(updatedAt).to.equal(0); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is above minimum and below maximum", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [3541, 496]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.getRoundData(123); + expect(roundId).to.equal(123); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[1]); + expect(startedAt).to.equal(0); + expect(updatedAt).to.equal(0); + expect(answeredInRound).to.equal(0); + }); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/latestRoundData.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/latestRoundData.ts new file mode 100644 index 00000000..ad3a6b03 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/latestRoundData.ts @@ -0,0 +1,137 @@ +import { DEFAULT_TWAP_INTERVAL, TICKS } from "@hifi/constants"; +import { expect } from "chai"; +import { ethers } from "hardhat"; + +import { calculateTick, tickToTokenPrices } from "../../../../shared/mirrors"; + +export function shouldBehaveLikeLatestRoundData(): void { + context("when token0 is the quote asset of the price feed", function () { + let token0Decimals: number; + let token1Decimals: number; + + beforeEach(async function () { + await this.mocks.pool.mock.token0.returns(this.mocks.usdc.address); + await this.mocks.pool.mock.token1.returns(this.mocks.wbtc.address); + await this.contracts.uniswapV3priceFeed.__godMode_setPool(this.mocks.pool.address); + await this.contracts.uniswapV3priceFeed.__godMode_setQuoteAsset(this.mocks.usdc.address); + token0Decimals = await this.mocks.usdc.decimals(); + token1Decimals = await this.mocks.wbtc.decimals(); + }); + + context("when sqrtPriceX96 is minimum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.lowerBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.latestRoundData(); + expect(roundId).to.equal(0); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[0]); + expect(startedAt).to.equal(0); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + expect(updatedAt).to.equal(timestamp); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is maximum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.upperBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.latestRoundData(); + expect(roundId).to.equal(0); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[0]); + expect(startedAt).to.equal(0); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + expect(updatedAt).to.equal(timestamp); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is above minimum and below maximum", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [3541, 496]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.latestRoundData(); + expect(roundId).to.equal(0); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[0]); + expect(startedAt).to.equal(0); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + expect(updatedAt).to.equal(timestamp); + expect(answeredInRound).to.equal(0); + }); + }); + }); + + context("when token1 is the quote asset of the price feed", function () { + let token0Decimals: number; + let token1Decimals: number; + + beforeEach(async function () { + await this.mocks.pool.mock.token0.returns(this.mocks.wbtc.address); + await this.mocks.pool.mock.token1.returns(this.mocks.usdc.address); + await this.contracts.uniswapV3priceFeed.__godMode_setPool(this.mocks.pool.address); + await this.contracts.uniswapV3priceFeed.__godMode_setQuoteAsset(this.mocks.usdc.address); + token0Decimals = await this.mocks.wbtc.decimals(); + token1Decimals = await this.mocks.usdc.decimals(); + }); + + context("when sqrtPriceX96 is minimum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.lowerBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.latestRoundData(); + expect(roundId).to.equal(0); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[1]); + expect(startedAt).to.equal(0); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + expect(updatedAt).to.equal(timestamp); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is maximum ", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [TICKS.upperBound, 0]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.latestRoundData(); + expect(roundId).to.equal(0); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[1]); + expect(startedAt).to.equal(0); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + expect(updatedAt).to.equal(timestamp); + expect(answeredInRound).to.equal(0); + }); + }); + + context("when sqrtPriceX96 is above minimum and below maximum", function () { + it("returns the correct value", async function () { + const tickCumulatives: number[] = [3541, 496]; + await this.mocks.pool.mock.observe.withArgs([DEFAULT_TWAP_INTERVAL, 0]).returns(tickCumulatives, [0, 0]); + const { roundId, answer, startedAt, updatedAt, answeredInRound } = + await this.contracts.uniswapV3priceFeed.latestRoundData(); + expect(roundId).to.equal(0); + const tick = calculateTick(tickCumulatives, DEFAULT_TWAP_INTERVAL); + const prices = tickToTokenPrices(tick, token0Decimals, token1Decimals); + expect(answer).to.equal(prices[1]); + expect(startedAt).to.equal(0); + const { timestamp }: { timestamp: number } = await ethers.provider.getBlock("latest"); + expect(updatedAt).to.equal(timestamp); + expect(answeredInRound).to.equal(0); + }); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/maxPrice.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/maxPrice.ts new file mode 100644 index 00000000..9e679887 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/maxPrice.ts @@ -0,0 +1,15 @@ +import { expect } from "chai"; + +export function shouldBehaveLikeMaxPrice(): void { + context("when the max price is set", function () { + beforeEach(async function () { + this.maxPrice = 1234; + await this.contracts.uniswapV3priceFeed.__godMode_setMaxPrice(this.maxPrice); + }); + + it("returns the max price", async function () { + const maxPrice = await this.contracts.uniswapV3priceFeed.maxPrice(); + expect(maxPrice).to.equal(this.maxPrice); + }); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/pool.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/pool.ts new file mode 100644 index 00000000..2cd3ddd6 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/pool.ts @@ -0,0 +1,8 @@ +import { expect } from "chai"; + +export function shouldBehaveLikePool(): void { + it("returns the Uniswap V3 pool", async function () { + const pool = await this.contracts.uniswapV3priceFeed.pool(); + expect(pool).to.equal(this.mocks.pool.address); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/quoteAsset.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/quoteAsset.ts new file mode 100644 index 00000000..68fa93a1 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/quoteAsset.ts @@ -0,0 +1,8 @@ +import { expect } from "chai"; + +export function shouldBehaveLikeQuoteAsset(): void { + it("returns the quote asset of the price feed", async function () { + const quoteAsset = await this.contracts.uniswapV3priceFeed.quoteAsset(); + expect(quoteAsset).to.equal(await this.mocks.pool.token0()); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/twapInterval.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/twapInterval.ts new file mode 100644 index 00000000..139058eb --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/twapInterval.ts @@ -0,0 +1,9 @@ +import { DEFAULT_TWAP_INTERVAL } from "@hifi/constants"; +import { expect } from "chai"; + +export function shouldBehaveLikeTwapInterval(): void { + it("returns the TWAP time window", async function () { + const twapInterval = await this.contracts.uniswapV3priceFeed.twapInterval(); + expect(twapInterval).to.equal(DEFAULT_TWAP_INTERVAL); + }); +} diff --git a/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/version.ts b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/version.ts new file mode 100644 index 00000000..9b9e20c9 --- /dev/null +++ b/packages/protocol/test/unit/oracles/uniswap-v3-price-feed/view/version.ts @@ -0,0 +1,8 @@ +import { expect } from "chai"; + +export function shouldBehaveLikeVersion(): void { + it("returns the price feed version", async function () { + const version = await this.contracts.uniswapV3priceFeed.version(); + expect(version).to.equal(1); + }); +} diff --git a/yarn.lock b/yarn.lock index eceacd68..88c1e0f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2396,6 +2396,7 @@ __metadata: "@types/node": ^17.0.23 "@typescript-eslint/eslint-plugin": ^5.17.0 "@typescript-eslint/parser": ^5.17.0 + "@uniswap/v3-sdk": ^3.9.0 chai: ^4.3.6 cross-env: ^7.0.3 dotenv: ^16.0.0 @@ -3401,8 +3402,8 @@ __metadata: linkType: hard "@uniswap/sdk-core@npm:^3.0.1, @uniswap/sdk-core@npm:^3.1.2": - version: 3.1.2 - resolution: "@uniswap/sdk-core@npm:3.1.2" + version: 3.2.2 + resolution: "@uniswap/sdk-core@npm:3.2.2" dependencies: "@ethersproject/address": ^5.0.2 big.js: ^5.2.2 @@ -3410,7 +3411,7 @@ __metadata: jsbi: ^3.1.4 tiny-invariant: ^1.1.0 toformat: ^2.0.0 - checksum: fbf98235e5724f150a54f9a5c11cd48a8c4508fbd913fdf7eb0fa4ffcaca86a8dab3baa41d1599682c04749860f463b5b63a412742a57df6ff8117b60078341b + checksum: 6a2b85ef429b2f19324764944f7de309e74509bcc7c4f869e4fb39b836e75d3efda6c842a35511e9e4747dddaf24c4675f2bf980668110e742c76bafab29e8b4 languageName: node linkType: hard