Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x6FfF62f96E6ADadC84bCeF64e6496dF9F1d6be2C
Balance 0 ETH
Nonce 1
Code Size 21913 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

21913 bytes
0x608060405234801561000f575f80fd5b5060043610610208575f3560e01c80638da5cb5b1161011f578063bf7e214f116100a9578063d21220a711610079578063d21220a71461050c578063df1f9f8e14610533578063ef056ab914610548578063f2fde38b1461055d578063faaf27d414610570575f80fd5b8063bf7e214f1461049f578063c1488069146104b2578063c6719f8c146104c5578063d0c93a7c146104e5575f80fd5b8063a882e575116100ef578063a882e57514610413578063aa290e6d14610426578063b187bd2614610439578063b777e0de1461045d578063bcee6fb51461048a575f80fd5b80638da5cb5b146103b357806394605857146103c5578063a3ff39b2146103ed578063a70fc00714610400575f80fd5b80633f4ba83a116101a057806370fa16ee1161017057806370fa16ee1461034a5780637a9e5e4b1461035d5780637f5a7c7b146103705780638456cb5914610383578063877887821461038b575f80fd5b80633f4ba83a146102f15780634e47a3fe146102f957806363bd1d4a1461030c578063643090bc1461031f575f80fd5b806333a9f811116101db57806333a9f811146102a257806333d735d8146102aa578063351a3df1146102cb57806337c59d6d146102de575f80fd5b8063089fe6aa1461020c5780630dfe16811461023b5780631d4161651461027a5780632f7409fc1461028f575b5f80fd5b60065461022290600160a01b900462ffffff1681565b60405162ffffff90911681526020015b60405180910390f35b6102627f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b6040516001600160a01b039091168152602001610232565b61028d6102883660046149d0565b610585565b005b61028d61029d366004614a01565b6105cb565b61028d6106c8565b6102bd6102b8366004614a32565b610703565b604051908152602001610232565b6102bd6102d9366004614a49565b610722565b6102bd6102ec366004614a49565b610952565b61028d610ca7565b600254610262906001600160a01b031681565b600454610262906001600160a01b031681565b600554610332906001600160801b031681565b6040516001600160801b039091168152602001610232565b61028d610358366004614a77565b610d0f565b61028d61036b366004614b03565b6115e3565b600654610262906001600160a01b031681565b61028d6116c7565b6002546103a090600160c01b900461ffff1681565b60405161ffff9091168152602001610232565b5f54610262906001600160a01b031681565b6103d86103d3366004614a32565b611735565b60408051928352602083019190915201610232565b61028d6103fb366004614b03565b6117eb565b61028d61040e366004614b1e565b61183e565b6102bd610421366004614a49565b611945565b61028d610434366004614b60565b611985565b60015461044d90600160a01b900460ff1681565b6040519015158152602001610232565b6003546104719067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610232565b6006546103a090600160e01b900461ffff1681565b600154610262906001600160a01b031681565b61028d6104c0366004614b79565b611a22565b6003546104719068010000000000000000900467ffffffffffffffff1681565b6006546104f990600160b81b900460020b81565b60405160029190910b8152602001610232565b6102627f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6002546103a090600160a01b900461ffff1681565b6006546103a090600160d01b900461ffff1681565b61028d61056b366004614b03565b611ab1565b6002546103a090600160b01b900461ffff1681565b61059a335f356001600160e01b031916611b2c565b6105bf5760405162461bcd60e51b81526004016105b690614ba5565b60405180910390fd5b6105c881611bd2565b50565b6105e0335f356001600160e01b031916611b2c565b6105fc5760405162461bcd60e51b81526004016105b690614ba5565b61271061ffff83161180610615575061232861ffff8316105b80610625575061271061ffff8216105b806106355750612af861ffff8216115b1561065357604051631e16f06160e01b815260040160405180910390fd5b6006805463ffffffff60d01b1916600160d01b61ffff85811691820261ffff60e01b191692909217600160e01b928516928302179092556040805192835260208301919091527f58d7af29c7c856c60817b08ed130d2e25ab433bdfd3c1ae53efb6ea99e4ac3b9910160405180910390a15050565b6106dd335f356001600160e01b031916611b2c565b6106f95760405162461bcd60e51b81526004016105b690614ba5565b610701611e28565b565b60098181548110610712575f80fd5b5f91825260209091200154905081565b600254604051633d8ceed960e01b8152600481018490527f000000000000000000000000000000000000000000000000000000000000001260ff16602482015261ffff600160a01b830481166044830152600160b01b83041660648201525f9184916001600160a01b0390911690633d8ceed9906084015f6040518083038186803b1580156107af575f80fd5b505afa1580156107c1573d5f803e3d5ffd5b505050505f806107d086612033565b915091508415610893575f6108067f0000000000000000000000000000000000000000000000000000000000000006600a614cbf565b6108109083614ccd565b90506108486108407f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b82908961215c565b90506108757f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b61087f9082614cf8565b905061088b8184614d17565b945050610949565b5f6108bf7f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b6108c99084614ccd565b9050610902876108fa7f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b83919061215c565b905061092f7f0000000000000000000000000000000000000000000000000000000000000006600a614cbf565b6109399082614cf8565b90506109458183614d17565b9450505b50505092915050565b600254604051633d8ceed960e01b8152600481018490527f000000000000000000000000000000000000000000000000000000000000001260ff16602482015261ffff600160a01b830481166044830152600160b01b83041660648201525f9184916001600160a01b0390911690633d8ceed9906084015f6040518083038186803b1580156109df575f80fd5b505afa1580156109f1573d5f803e3d5ffd5b505050505f7f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a769190614d2a565b9050805f03610c58577f00000000000000000000000000000000000000000000000000000000000000008015610aa95750835b15610ae157610ad97f0000000000000000000000000000000000000000000000000000000000000006600a614cbf565b925050610ca0565b7f0000000000000000000000000000000000000000000000000000000000000000158015610b0c5750835b15610b7257610ad9610b3f7f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b86610b6b7f0000000000000000000000000000000000000000000000000000000000000006600a614cbf565b919061215c565b7f00000000000000000000000000000000000000000000000000000000000000008015610b9d575083155b15610bfc57610ad985610bd17f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b610b6b7f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b7f0000000000000000000000000000000000000000000000000000000000000000158015610c28575083155b1561020857610ad97f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b5f610c638686610722565b9050610c9b610c937f0000000000000000000000000000000000000000000000000000000000000012600a614cbf565b82908461215c565b935050505b5092915050565b610cbc335f356001600160e01b031916611b2c565b610cd85760405162461bcd60e51b81526004016105b690614ba5565b6001805460ff60a01b191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933905f90a1565b600254604051633d8ceed960e01b8152600481018590527f000000000000000000000000000000000000000000000000000000000000001260ff16602482015261ffff600160a01b830481166044830152600160b01b830416606482015284916001600160a01b031690633d8ceed9906084015f6040518083038186803b158015610d98575f80fd5b505afa158015610daa573d5f803e3d5ffd5b50505050610dc3335f356001600160e01b031916611b2c565b610ddf5760405162461bcd60e51b81526004016105b690614ba5565b610de7611e28565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316610e1d57610e1d612177565b5f7f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e7a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9e9190614d2a565b90505f610ecb867f0000000000000000000000000000000000000000000000000000000000000000610722565b90505f5b848110156113ac5736868683818110610eea57610eea614d41565b9050602002810190610efc9190614d55565b90505f610f0c6020830183614d87565b600d811115610f1d57610f1d614d73565b03610f4e575f610f306020830183614da5565b810190610f3d9190614a32565b9050610f4881612381565b506113a3565b6001610f5d6020830183614d87565b600d811115610f6e57610f6e614d73565b03610f99575f610f816020830183614da5565b810190610f8e9190614a32565b9050610f488161247e565b6002610fa86020830183614d87565b600d811115610fb957610fb9614d73565b03610fef575f80610fcd6020840184614da5565b810190610fda9190614def565b91509150610fe88282612539565b50506113a3565b6003610ffe6020830183614d87565b600d81111561100f5761100f614d73565b0361103e575f806110236020840184614da5565b8101906110309190614def565b91509150610fe88282612649565b600461104d6020830183614d87565b600d81111561105e5761105e614d73565b0361108d575f806110726020840184614da5565b81019061107f9190614def565b91509150610fe882826126c6565b600561109c6020830183614d87565b600d8111156110ad576110ad614d73565b036110dc575f806110c16020840184614da5565b8101906110ce9190614def565b91509150610fe88282612743565b60066110eb6020830183614d87565b600d8111156110fc576110fc614d73565b03611146575f80808080806111146020880188614da5565b8101906111219190614e4c565b95509550955095509550955061113b8686868686866127c0565b5050505050506113a3565b60076111556020830183614d87565b600d81111561116657611166614d73565b036111a6575f80808061117c6020860186614da5565b8101906111899190614ea7565b935093509350935061119d84848484612c6a565b505050506113a3565b60086111b56020830183614d87565b600d8111156111c6576111c6614d73565b0361120b575f808080806111dd6020870187614da5565b8101906111ea9190614ed6565b945094509450945094506112018585858585612deb565b50505050506113a3565b600961121a6020830183614d87565b600d81111561122b5761122b614d73565b03611266575f808080806112426020870187614da5565b81019061124f9190614ed6565b9450945094509450945061120185858585856130b8565b600a6112756020830183614d87565b600d81111561128657611286614d73565b036112b5575f8061129a6020840184614da5565b8101906112a79190614f18565b91509150610fe88282613244565b600b6112c46020830183614d87565b600d8111156112d5576112d5614d73565b0361130c575f8080806112eb6020860186614da5565b8101906112f89190614ff6565b935093509350935061119d848484846133be565b600c61131b6020830183614d87565b600d81111561132c5761132c614d73565b03611342575f8080806112eb6020860186614da5565b600d6113516020830183614d87565b600d81111561136257611362614d73565b036113a3575f808080806113796020870187614da5565b810190611386919061505a565b9450945094509450945061139d85858585856137de565b50505050505b50600101610ecf565b507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03166113e3576113e3613f02565b6113eb611e28565b7f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611447573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146b9190614d2a565b821461148a5760405163eeaed42d60e01b815260040160405180910390fd5b5f6114b5877f0000000000000000000000000000000000000000000000000000000000000000610722565b6006549091505f906114d6908490600160d01b900461ffff1661271061215c565b6006549091505f906114f7908590600160e01b900461ffff1661271061215c565b90508183108061150657508083115b15611535576040516314da049160e11b81526004810184905260248101839052604481018290526064016105b6565b838311156115b0575f61154885856150cb565b6002549091506115709061156b908390600160c01b900461ffff1661271061215c565b613fc7565b600580545f9061158a9084906001600160801b03166150de565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505b6040517fc741dbaad15a4f298fe8d80943fa8e005e7bcb2f5b0a0c8dec1fc35be457f146905f90a1505050505050505050565b5f546001600160a01b0316331480611674575060015460405163b700961360e01b81526001600160a01b039091169063b70096139061163590339030906001600160e01b03195f3516906004016150fe565b602060405180830381865afa158015611650573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611674919061512b565b61167c575f80fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350565b6116dc335f356001600160e01b031916611b2c565b6116f85760405162461bcd60e51b81526004016105b690614ba5565b6001805460ff60a01b1916600160a01b1790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e752905f90a1565b600254604051633d8ceed960e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000001260ff16602482015261ffff600160a01b830481166044830152600160b01b83041660648201525f91829184916001600160a01b031690633d8ceed9906084015f6040518083038186803b1580156117c2575f80fd5b505afa1580156117d4573d5f803e3d5ffd5b505050506117e184612033565b9250925050915091565b611800335f356001600160e01b031916611b2c565b61181c5760405162461bcd60e51b81526004016105b690614ba5565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b611853335f356001600160e01b031916611b2c565b61186f5760405162461bcd60e51b81526004016105b690614ba5565b600280546001600160a01b0319166001600160a01b03851617905561271061ffff831611806118a3575061232861ffff8316105b806118b3575061271061ffff8216105b806118c35750612af861ffff8216115b156118e1576040516324f28deb60e21b815260040160405180910390fd5b6002805461ffff838116600160b01b0261ffff60b01b19918616600160a01b029190911663ffffffff60a01b19909216919091171790556040517f397435eb1fe97be3db1f7727ab797f78286491798538da504edb9959729f1c25905f90a1505050565b6001545f90600160a01b900460ff1615611972576040516332b2a8fd60e11b815260040160405180910390fd5b61197c8383610952565b90505b92915050565b61199a335f356001600160e01b031916611b2c565b6119b65760405162461bcd60e51b81526004016105b690614ba5565b610bb861ffff821611156119dd5760405163343b369760e11b815260040160405180910390fd5b6002805461ffff60c01b1916600160c01b61ffff8416021790556040517f22127ba1e773276f27b9d2d937ba811f4a2adf2575b51cb9c291fde17803c0d6905f90a150565b611a37335f356001600160e01b031916611b2c565b611a535760405162461bcd60e51b81526004016105b690614ba5565b6001600160a01b0382165f81815260076020908152604091829020805460ff191685151590811790915591519182527fec57dfb25ceb91824ddcccf9134e3dec0e7de69251394efb93c925315aa32f30910160405180910390a25050565b611ac6335f356001600160e01b031916611b2c565b611ae25760405162461bcd60e51b81526004016105b690614ba5565b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6001545f906001600160a01b03168015801590611bb3575060405163b700961360e01b81526001600160a01b0382169063b700961390611b74908790309088906004016150fe565b602060405180830381865afa158015611b8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bb3919061512b565b80611bca57505f546001600160a01b038581169116145b949350505050565b6005546001600160801b03168015611e24575f82611c10577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2611c32565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485b600580546001600160801b031916905590506001600160a01b038116611d4c5760048054604080516001600160a01b039283166024820152604480820187905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b1790529051630f6e715d60e41b81527f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e519092169263f6e715d092611d04927f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29290915f9101615193565b5f604051808303815f875af1158015611d1f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611d4691908101906151c6565b50611e22565b60048054604080516001600160a01b039283166024820152604480820187905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b1790529051630f6e715d60e41b81527f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e519092169263f6e715d092611dde92869290915f9101615193565b5f604051808303815f875af1158015611df9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e2091908101906151c6565b505b505b5050565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031615611f0b576040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e5181166004830152611f06917f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48909116906370a08231906024015b602060405180830381865afa158015611ee2573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061156b9190614d2a565b611f7f565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e5181166004830152611f7f917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2909116906370a0823190602401611ec7565b600880546001600160801b0319166001600160801b03929092169190911790556040516370a0823160e01b81527f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b039081166004830152612014917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2909116906370a0823190602401611ec7565b600880546001600160801b03928316600160801b029216919091179055565b6008546001600160801b0380821691600160801b9004165f61208484600160c01b61207f7f0000000000000000000000000000000000000000000000000000000000000006600a614cbf565b613ffe565b90505f6120986120938361409b565b6140f3565b600a549091505f5b81811015612153575f600a82815481106120bc576120bc614d41565b5f91825260208083206040805160608101825293909101546001600160801b0381168452600160801b8104600290810b938501849052600160981b909104900b90830152909250819061212890879061211490614126565b6121218660400151614126565b8651614441565b9092509050612137828a614d17565b98506121438189614d17565b97505050508060010190506120a0565b50505050915091565b5f825f190484118302158202612170575f80fd5b5091020490565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51811660048301525f917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2909116906370a0823190602401602060405180830381865afa1580156121ff573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122239190614d2a565b1115610701576040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e518116600483018190529163f6e715d0917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d60e01b918316906370a0823190602401602060405180830381865afa1580156122c1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e59190614d2a565b6040516024016122f791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e085901b909216825261233f92915f90600401615193565b5f604051808303815f875af115801561235a573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526105c891908101906151c6565b604080516e22d473030f116ddee9f6b43ac78ba36024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663095ea7b360e01b1790529051630f6e715d60e41b81527f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b03169063f6e715d09061243c907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489085905f90600401615193565b5f604051808303815f875af1158015612457573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e2291908101906151c6565b604080516e22d473030f116ddee9f6b43ac78ba36024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663095ea7b360e01b1790529051630f6e715d60e41b81527f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b03169063f6e715d09061243c907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29085905f90600401615193565b5f60405160200161254990615238565b604051602081830303815290604052805190602001207f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f000000000000000000000000bd216513d74c8cf14cf4747e6aaa6420ff64ee9e85856040516024016125b69493929190615271565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051630f6e715d60e41b81529091506001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51169063f6e715d090611dde906e22d473030f116ddee9f6b43ac78ba39085905f90600401615193565b5f60405160200161265990615238565b604051602081830303815290604052805190602001207f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000bd216513d74c8cf14cf4747e6aaa6420ff64ee9e85856040516024016125b69493929190615271565b5f6040516020016126d690615238565b604051602081830303815290604052805190602001207f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f00000000000000000000000066a9893cc07d91d95644aedd05d03f95e1dba8af85856040516024016125b69493929190615271565b5f60405160200161275390615238565b604051602081830303815290604052805190602001207f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f00000000000000000000000066a9893cc07d91d95644aedd05d03f95e1dba8af85856040516024016125b69493929190615271565b5f6002600d6014806040516020016127db94939291906152a2565b60408051808303601f19018152600480845260a0840190925292505f9190816020015b60608152602001906001900390816127fe579050506040805160a0810182526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811682527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2811660208084019190915260065462ffffff600160a01b82041684860152600160b81b810460020b606085015290911660808301529151929350916128de9183918c918c918c918c918c917f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51910161531a565b604051602081830303815290604052825f815181106128ff576128ff614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040516020016129729291906001600160a01b0392831681529116602082015260400190565b6040516020818303038152906040528260018151811061299457612994614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51604051602001612a079291906001600160a01b0392831681529116602082015260400190565b60405160208183030381529060405282600281518110612a2957612a29614d41565b60200260200101819052507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51604051602001612a9c9291906001600160a01b0392831681529116602082015260400190565b60405160208183030381529060405282600381518110612abe57612abe614d41565b60200260200101819052505f7f000000000000000000000000bd216513d74c8cf14cf4747e6aaa6420ff64ee9e6001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4a9190614d2a565b9050612b8d8484877f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031615612b87575f6144dc565b8a6144dc565b6009805460018082019092557f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0191909155604080516060810182526001600160801b03998a16815260029b8c0b602082019081529a909b0b908b01908152600a805492830181555f5299517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8909101805499519a51919098166001600160981b031990991698909817600160801b62ffffff9a8b16021762ffffff60981b1916600160981b999098169890980296909617909455505050505050565b612c73846145fd565b5f60036011604051602001612c89929190615384565b60408051808303601f1901815260028084526060840190925292505f9190816020015b6060815260200190600190039081612cac579050506040805160208101899052908101879052606081018690526080808201525f60a082015290915060c001604051602081830303815290604052815f81518110612d0c57612d0c614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51604051602001612daa939291906001600160a01b0393841681529183166020830152909116604082015260600190565b60405160208183030381529060405281600181518110612dcc57612dcc614d41565b6020026020010181905250612de38282855f6144dc565b505050505050565b5f80600d601480604051602001612e0594939291906152a2565b60408051808303601f19018152600480845260a0840190925292505f9190816020015b6060815260200190600190039081612e285790505060408051602081018a90526001600160801b03891691810191909152606081018790526080810186905260a0808201525f60c082015290915060e001604051602081830303815290604052815f81518110612e9a57612e9a614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2604051602001612f0d9291906001600160a01b0392831681529116602082015260400190565b60405160208183030381529060405281600181518110612f2f57612f2f614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51604051602001612fa29291906001600160a01b0392831681529116602082015260400190565b60405160208183030381529060405281600281518110612fc457612fc4614d41565b60200260200101819052507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516040516020016130379291906001600160a01b0392831681529116602082015260400190565b6040516020818303038152906040528160038151811061305957613059614d41565b60209081029190910101526130a58282857f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03161561309f575f6144dc565b886144dc565b6130af878761478b565b50505050505050565b5f600160116040516020016130ce929190615384565b60408051808303601f1901815260028084526060840190925292505f9190816020015b60608152602001906001900390816130f15790505060408051602081018a90526001600160801b03891691810191909152606081018790526080810186905260a0808201525f60c082015290915060e001604051602081830303815290604052815f8151811061316357613163614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51604051602001613201939291906001600160a01b0393841681529183166020830152909116604082015260600190565b6040516020818303038152906040528160018151811061322357613223614d41565b602002602001018190525061323a8282855f6144dc565b6130af878761484d565b5f6001601160405160200161325a929190615384565b60408051808303601f1901815260028084526060840190925292505f9190816020015b606081526020019060019003908161327d5790505060408051602081018790525f918101829052606081018290526080810182905260a08082015260c081019190915290915060e001604051602081830303815290604052815f815181106132e7576132e7614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51604051602001613385939291906001600160a01b0393841681529183166020830152909116604082015260600190565b604051602081830303815290604052816001815181106133a7576133a7614d41565b6020026020010181905250611e208282855f6144dc565b60408051600160fc1b602082015281516001818303018152602182018352600360f91b6041830152600360fa1b6042830152600f60f81b60438301528251602481840301815260036044840181815260c48501909552919390925f92906064015b606081526020019060019003908161341f579050506040805160a080820183526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811683527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2811660208085019190915260065462ffffff600160a01b82041685870152600160b81b810460020b6060808701919091529216608080860191909152855193840186528484526001848301526001600160801b03808f16858801528d16928401929092529082018990529251939450909261350892016153a6565b604051602081830303815290604052825f8151811061352957613529614d41565b60200260200101819052507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48886040516020016135849291906001600160a01b039290921682526001600160801b0316602082015260400190565b604051602081830303815290604052826001815181106135a6576135a6614d41565b60200260200101819052507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2876040516020016136019291906001600160a01b039290921682526001600160801b0316602082015260400190565b6040516020818303038152906040528260028151811061362357613623614d41565b60209081029190910101526040805160018082528183019092525f91816020015b6060815260200190600190039081613644579050509050838360405160200161366e929190615459565b604051602081830303815290604052815f8151811061368f5761368f614d41565b60200260200101819052505f633593564c60e01b86838a6040516024016136b89392919061547d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e5181169063f6e715d0907f00000000000000000000000066a9893cc07d91d95644aedd05d03f95e1dba8af9084907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48161561376f575f613771565b8d5b6040518463ffffffff1660e01b815260040161378f939291906154b2565b5f604051808303815f875af11580156137aa573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526137d191908101906151c6565b5050505050505050505050565b6001600160a01b0385165f9081526007602052604081205460ff161515900361381a57604051632455671d60e01b815260040160405180910390fd5b604080516001600160a01b038716602482015260448082018790528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052831561394f577f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03161561394a57604051630f6e715d60e41b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51169063f6e715d090613906907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489085905f90600401615193565b5f604051808303815f875af1158015613921573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261394891908101906151c6565b505b613a03565b604051630f6e715d60e41b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51169063f6e715d0906139bf907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29085905f90600401615193565b5f604051808303815f875af11580156139da573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613a0191908101906151c6565b505b5f7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031615613ae0576040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51811660048301527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa158015613ab7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613adb9190614d2a565b613b0c565b7f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b0316315b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51811660048301529192505f917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a0823190602401602060405180830381865afa158015613b95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bb99190614d2a565b90507f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b031663f6e715d08986898015613c2057507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316155b613c2a575f613c2c565b8a5b6040518463ffffffff1660e01b8152600401613c4a93929190615193565b5f604051808303815f875af1158015613c65573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c8c91908101906151c6565b505f7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031615613d6a576040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51811660048301527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa158015613d41573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d659190614d2a565b613d96565b7f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e516001600160a01b0316315b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51811660048301529192505f917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a0823190602401602060405180830381865afa158015613e1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e439190614d2a565b90508715613ea35788613e5683866150cb565b14613e74576040516302304dc560e41b815260040160405180910390fd5b86613e7f84836150cb565b1015613e9e576040516302b684ff60e41b815260040160405180910390fd5b613ef6565b88613eae82856150cb565b14613ecc576040516302b684ff60e41b815260040160405180910390fd5b86613ed785846150cb565b1015613ef6576040516302304dc560e41b815260040160405180910390fd5b50505050505050505050565b6001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51163115610701576040805160048082526024820183526020820180516001600160e01b0316630d0e30db60e41b1790529151630f6e715d60e41b81526001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51169263f6e715d09261233f927f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29286319101615193565b5f6001600160801b03821115613ffa576040516306dfcc6560e41b815260806004820152602481018390526044016105b6565b5090565b5f838302815f198587098281108382030391505080841161401d575f80fd5b805f0361402f57508290049050614094565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150505b9392505050565b5f8060026140aa846001614d17565b6140b49190614cf8565b90508291505b818110156140ed579050806002816140d28186614cf8565b6140dc9190614d17565b6140e69190614cf8565b90506140ba565b50919050565b5f6001600160a01b03821115613ffa576040516306dfcc6560e41b815260a06004820152602481018390526044016105b6565b5f805f8360020b1261413b578260020b614142565b8260020b5f035b9050620d89e8811115614168576040516315e4079d60e11b815260040160405180910390fd5b5f816001165f0361417d57600160801b61418f565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff16905060028216156141c3576ffff97272373d413259a46990580e213a0260801c5b60048216156141e2576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614201576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615614220576fffcb9843d60f6159c9db58835c9266440260801c5b602082161561423f576fff973b41fa98c081472e6896dfb254c00260801c5b604082161561425e576fff2ea16466c96a3843ec78b326b528610260801c5b608082161561427d576ffe5dee046a99a2a811c461f1969c30530260801c5b61010082161561429d576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156142bd576ff987a7253ac413176f2b074cf7815e540260801c5b6104008216156142dd576ff3392b0822b70005940c7a398e4b70f30260801c5b6108008216156142fd576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161561431d576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161561433d576fa9f746462d870fdf8a65dc1f90e061e50260801c5b61400082161561435d576f70d869a156d2a1b890bb3df62baf32f70260801c5b61800082161561437d576f31be135f97d08fd981231505542fcfa60260801c5b6201000082161561439e576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156143be576e5d6af8dedb81196699c329225ee6040260801c5b620400008216156143dd576d2216e584f5fa1ea926041bedfe980260801c5b620800008216156143fa576b048a170391f7dc42444e8fa20260801c5b5f8460020b131561441957805f198161441557614415614ce4565b0490505b64010000000081061561442d57600161442f565b5f5b60ff16602082901c0192505050919050565b5f80836001600160a01b0316856001600160a01b03161115614461579293925b846001600160a01b0316866001600160a01b03161161448c576144858585856148cd565b91506144d3565b836001600160a01b0316866001600160a01b031610156144c5576144b18685856148cd565b91506144be85878561493f565b90506144d3565b6144d085858561493f565b90505b94509492505050565b5f63dd46508f60e01b85856040516020016144f8929190615459565b60408051601f19818403018152908290526145179186906024016154ee565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051630f6e715d60e41b81529091506001600160a01b037f0000000000000000000000003ad66a1b09a46f66089cda1829f5ccb3d43b8e51169063f6e715d0906145bb907f000000000000000000000000bd216513d74c8cf14cf4747e6aaa6420ff64ee9e9085908790600401615193565b5f604051808303815f875af11580156145d6573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612de391908101906151c6565b6009545f195f5b8281101561463e576009818154811061461f5761461f614d41565b905f5260205f20015484036146365780915061463e565b600101614604565b505f198114611e225760096146546001846150cb565b8154811061466457614664614d41565b905f5260205f2001546009828154811061468057614680614d41565b5f91825260209091200155600a6146986001846150cb565b815481106146a8576146a8614d41565b905f5260205f2001600a82815481106146c3576146c3614d41565b5f91825260209091208254910180546001600160801b039092166001600160801b031983168117825583546001600160981b031990931617600160801b9283900462ffffff90811690930217808255925462ffffff60981b19909316600160981b9384900490921690920217905560098054806147425761474261550f565b600190038181905f5260205f20015f90559055600a8054806147665761476661550f565b5f8281526020902081015f1990810180546001600160b01b0319169055019055505050565b6009545f195f5b828110156147cc57600981815481106147ad576147ad614d41565b905f5260205f20015485036147c4578091506147cc565b600101614792565b505f1981146148345782600a82815481106147e9576147e9614d41565b5f9182526020822001805490919061480b9084906001600160801b03166150de565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550611e20565b604051632caf4f6b60e01b815260040160405180910390fd5b6009545f195f5b8281101561488e576009818154811061486f5761486f614d41565b905f5260205f20015485036148865780915061488e565b600101614854565b505f1981146148345782600a82815481106148ab576148ab614d41565b5f9182526020822001805490919061480b9084906001600160801b0316615523565b5f826001600160a01b0316846001600160a01b031611156148ec579192915b6001600160a01b0384166149356fffffffffffffffffffffffffffffffff60601b606085901b1661491d8787615543565b6001600160a01b0316866001600160a01b0316614984565b611bca9190614cf8565b5f826001600160a01b0316846001600160a01b0316111561495e579192915b611bca6001600160801b0383166149758686615543565b6001600160a01b0316600160601b5b5f80805f19858709858702925082811083820303915050805f036149b8575f84116149ad575f80fd5b508290049050614094565b80841161402f575f80fd5b80151581146105c8575f80fd5b5f602082840312156149e0575f80fd5b8135614094816149c3565b803561ffff811681146149fc575f80fd5b919050565b5f8060408385031215614a12575f80fd5b614a1b836149eb565b9150614a29602084016149eb565b90509250929050565b5f60208284031215614a42575f80fd5b5035919050565b5f8060408385031215614a5a575f80fd5b823591506020830135614a6c816149c3565b809150509250929050565b5f805f60408486031215614a89575f80fd5b83359250602084013567ffffffffffffffff80821115614aa7575f80fd5b818601915086601f830112614aba575f80fd5b813581811115614ac8575f80fd5b8760208260051b8501011115614adc575f80fd5b6020830194508093505050509250925092565b6001600160a01b03811681146105c8575f80fd5b5f60208284031215614b13575f80fd5b813561409481614aef565b5f805f60608486031215614b30575f80fd5b8335614b3b81614aef565b9250614b49602085016149eb565b9150614b57604085016149eb565b90509250925092565b5f60208284031215614b70575f80fd5b61197c826149eb565b5f8060408385031215614b8a575f80fd5b8235614b9581614aef565b91506020830135614a6c816149c3565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b600181815b80851115614c1957815f1904821115614bff57614bff614bcb565b80851615614c0c57918102915b93841c9390800290614be4565b509250929050565b5f82614c2f5750600161197f565b81614c3b57505f61197f565b8160018114614c515760028114614c5b57614c77565b600191505061197f565b60ff841115614c6c57614c6c614bcb565b50506001821b61197f565b5060208310610133831016604e8410600b8410161715614c9a575081810a61197f565b614ca48383614bdf565b805f1904821115614cb757614cb7614bcb565b029392505050565b5f61197c60ff841683614c21565b808202811582820484141761197f5761197f614bcb565b634e487b7160e01b5f52601260045260245ffd5b5f82614d1257634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561197f5761197f614bcb565b5f60208284031215614d3a575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f8235603e19833603018112614d69575f80fd5b9190910192915050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215614d97575f80fd5b8135600e8110614094575f80fd5b5f808335601e19843603018112614dba575f80fd5b83018035915067ffffffffffffffff821115614dd4575f80fd5b602001915036819003821315614de8575f80fd5b9250929050565b5f8060408385031215614e00575f80fd5b8235614e0b81614aef565b9150602083013565ffffffffffff81168114614a6c575f80fd5b8035600281900b81146149fc575f80fd5b80356001600160801b03811681146149fc575f80fd5b5f805f805f8060c08789031215614e61575f80fd5b614e6a87614e25565b9550614e7860208801614e25565b9450614e8660408801614e36565b9350606087013592506080870135915060a087013590509295509295509295565b5f805f8060808587031215614eba575f80fd5b5050823594602084013594506040840135936060013592509050565b5f805f805f60a08688031215614eea575f80fd5b85359450614efa60208701614e36565b94979496505050506040830135926060810135926080909101359150565b5f8060408385031215614f29575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614f7557614f75614f38565b604052919050565b5f67ffffffffffffffff821115614f9657614f96614f38565b50601f01601f191660200190565b5f82601f830112614fb3575f80fd5b8135614fc6614fc182614f7d565b614f4c565b818152846020838601011115614fda575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215615009575f80fd5b61501285614e36565b935061502060208601614e36565b925060408501359150606085013567ffffffffffffffff811115615042575f80fd5b61504e87828801614fa4565b91505092959194509250565b5f805f805f60a0868803121561506e575f80fd5b853561507981614aef565b9450602086013593506040860135615090816149c3565b925060608601359150608086013567ffffffffffffffff8111156150b2575f80fd5b6150be88828901614fa4565b9150509295509295909350565b8181038181111561197f5761197f614bcb565b6001600160801b03818116838216019080821115610ca057610ca0614bcb565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b5f6020828403121561513b575f80fd5b8151614094816149c3565b5f5b83811015615160578181015183820152602001615148565b50505f910152565b5f815180845261517f816020860160208601615146565b601f01601f19169290920160200192915050565b6001600160a01b03841681526060602082018190525f906151b690830185615168565b9050826040830152949350505050565b5f602082840312156151d6575f80fd5b815167ffffffffffffffff8111156151ec575f80fd5b8201601f810184136151fc575f80fd5b805161520a614fc182614f7d565b81815285602083850101111561521e575f80fd5b61522f826020830160208601615146565b95945050505050565b7f617070726f766528616464726573732c616464726573732c75696e743136302c81526675696e7434382960c81b602082015260270190565b6001600160a01b03948516815292841660208401529216604082015265ffffffffffff909116606082015260800190565b6001600160f81b031960f895861b8116825293851b8416600182015291841b8316600283015290921b16600382015260040190565b80516001600160a01b03908116835260208083015182169084015260408083015162ffffff169084015260608083015160020b9084015260809182015116910152565b5f610180615328838b6152d7565b600298890b60a08401529690970b60c08201526001600160801b039490941660e08501526101008401929092526101208301526001600160a01b031661014082015261016081018290525f918101919091526101a00192915050565b6001600160f81b031960f893841b811682529190921b16600182015260020190565b602081526153b86020820183516152d7565b6020820151151560c082015260408201516001600160801b0390811660e08301526060830151166101008201526080820151610120808301525f90611bca610140840182615168565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561544c57601f1986840301895261543a838351615168565b9884019892509083019060010161541e565b5090979650505050505050565b604081525f61546b6040830185615168565b828103602084015261522f8185615401565b606081525f61548f6060830186615168565b82810360208401526154a18186615401565b915050826040830152949350505050565b6001600160a01b03841681526060602082018190525f906154d590830185615168565b90506001600160801b0383166040830152949350505050565b604081525f6155006040830185615168565b90508260208301529392505050565b634e487b7160e01b5f52603160045260245ffd5b6001600160801b03828116828216039080821115610ca057610ca0614bcb565b6001600160a01b03828116828216039080821115610ca057610ca0614bcb56fea2646970667358221220258b00b23fb284bf0a65504753698ab0b765783dbb609540bf7a232dac01aaa264736f6c63430008180033

Verified Source Code Partial Match

Compiler: v0.8.24+commit.e11b9ed9 EVM: shanghai Optimization: Yes (200 runs)
UniswapV4FluxManager.sol 27008 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity <0.9.0 =0.8.24 >=0.4.0 >=0.4.22 >=0.5.0 >=0.6.0 >=0.6.2 >=0.8.0 ^0.8.0 ^0.8.20 ^0.8.24;
pragma experimental ABIEncoderV2;

// lib/v4-periphery/src/libraries/Actions.sol

/// @notice Library to define different pool actions.
/// @dev These are suggested common commands, however additional commands should be defined as required
/// Some of these actions are not supported in the Router contracts or Position Manager contracts, but are left as they may be helpful commands for other peripheral contracts.
library Actions {
    // pool actions
    // liquidity actions
    uint256 internal constant INCREASE_LIQUIDITY = 0x00;
    uint256 internal constant DECREASE_LIQUIDITY = 0x01;
    uint256 internal constant MINT_POSITION = 0x02;
    uint256 internal constant BURN_POSITION = 0x03;
    uint256 internal constant INCREASE_LIQUIDITY_FROM_DELTAS = 0x04;
    uint256 internal constant MINT_POSITION_FROM_DELTAS = 0x05;

    // swapping
    uint256 internal constant SWAP_EXACT_IN_SINGLE = 0x06;
    uint256 internal constant SWAP_EXACT_IN = 0x07;
    uint256 internal constant SWAP_EXACT_OUT_SINGLE = 0x08;
    uint256 internal constant SWAP_EXACT_OUT = 0x09;

    // donate
    // note this is not supported in the position manager or router
    uint256 internal constant DONATE = 0x0a;

    // closing deltas on the pool manager
    // settling
    uint256 internal constant SETTLE = 0x0b;
    uint256 internal constant SETTLE_ALL = 0x0c;
    uint256 internal constant SETTLE_PAIR = 0x0d;
    // taking
    uint256 internal constant TAKE = 0x0e;
    uint256 internal constant TAKE_ALL = 0x0f;
    uint256 internal constant TAKE_PORTION = 0x10;
    uint256 internal constant TAKE_PAIR = 0x11;

    uint256 internal constant CLOSE_CURRENCY = 0x12;
    uint256 internal constant CLEAR_OR_TAKE = 0x13;
    uint256 internal constant SWEEP = 0x14;

    uint256 internal constant WRAP = 0x15;
    uint256 internal constant UNWRAP = 0x16;

    // minting/burning 6909s to close deltas
    // note this is not supported in the position manager or router
    uint256 internal constant MINT_6909 = 0x17;
    uint256 internal constant BURN_6909 = 0x18;
}

// lib/solmate/src/auth/Auth.sol

/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
    event OwnershipTransferred(address indexed user, address indexed newOwner);

    event AuthorityUpdated(address indexed user, Authority indexed newAuthority);

    address public owner;

    Authority public authority;

    constructor(address _owner, Authority _authority) {
        owner = _owner;
        authority = _authority;

        emit OwnershipTransferred(msg.sender, _owner);
        emit AuthorityUpdated(msg.sender, _authority);
    }

    modifier requiresAuth() virtual {
        require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");

        _;
    }

    function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
        Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.

        // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
        // aware that this makes protected functions uncallable even to the owner if the authority is out of order.
        return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
    }

    function setAuthority(Authority newAuthority) public virtual {
        // We check if the caller is the owner first because we want to ensure they can
        // always swap out the authority even if it's reverting or using up a lot of gas.
        require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));

        authority = newAuthority;

        emit AuthorityUpdated(msg.sender, newAuthority);
    }

    function transferOwnership(address newOwner) public virtual requiresAuth {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
    function canCall(
        address user,
        address target,
        bytes4 functionSig
    ) external view returns (bool);
}

// lib/v4-core/src/types/BeforeSwapDelta.sol

// Return type of the beforeSwap hook.
// Upper 128 bits is the delta in specified tokens. Lower 128 bits is delta in unspecified tokens (to match the afterSwap hook)
type BeforeSwapDelta is int256;

// Creates a BeforeSwapDelta from specified and unspecified
function toBeforeSwapDelta(int128 deltaSpecified, int128 deltaUnspecified)
    pure
    returns (BeforeSwapDelta beforeSwapDelta)
{
    assembly ("memory-safe") {
        beforeSwapDelta := or(shl(128, deltaSpecified), and(sub(shl(128, 1), 1), deltaUnspecified))
    }
}

/// @notice Library for getting the specified and unspecified deltas from the BeforeSwapDelta type
library BeforeSwapDeltaLibrary {
    /// @notice A BeforeSwapDelta of 0
    BeforeSwapDelta public constant ZERO_DELTA = BeforeSwapDelta.wrap(0);

    /// extracts int128 from the upper 128 bits of the BeforeSwapDelta
    /// returned by beforeSwap
    function getSpecifiedDelta(BeforeSwapDelta delta) internal pure returns (int128 deltaSpecified) {
        assembly ("memory-safe") {
            deltaSpecified := sar(128, delta)
        }
    }

    /// extracts int128 from the lower 128 bits of the BeforeSwapDelta
    /// returned by beforeSwap and afterSwap
    function getUnspecifiedDelta(BeforeSwapDelta delta) internal pure returns (int128 deltaUnspecified) {
        assembly ("memory-safe") {
            deltaUnspecified := signextend(15, delta)
        }
    }
}

// src/interfaces/BeforeTransferHook.sol

interface BeforeTransferHook {
    function beforeTransfer(address from, address to, address operator) external view;
}

// src/libraries/Commands.sol

/// @title Commands
/// @notice Command Flags used to decode commands
/// @dev Copied from https://github.com/Uniswap/universal-router/blob/main/contracts/libraries/Commands.sol
library Commands {
    // Masks to extract certain bits of commands
    bytes1 internal constant FLAG_ALLOW_REVERT = 0x80;
    bytes1 internal constant COMMAND_TYPE_MASK = 0x3f;

    // Command Types. Maximum supported command at this moment is 0x3f.
    // The commands are executed in nested if blocks to minimise gas consumption

    // Command Types where value<=0x07, executed in the first nested-if block
    uint256 constant V3_SWAP_EXACT_IN = 0x00;
    uint256 constant V3_SWAP_EXACT_OUT = 0x01;
    uint256 constant PERMIT2_TRANSFER_FROM = 0x02;
    uint256 constant PERMIT2_PERMIT_BATCH = 0x03;
    uint256 constant SWEEP = 0x04;
    uint256 constant TRANSFER = 0x05;
    uint256 constant PAY_PORTION = 0x06;
    // COMMAND_PLACEHOLDER = 0x07;

    // Command Types where 0x08<=value<=0x0f, executed in the second nested-if block
    uint256 constant V2_SWAP_EXACT_IN = 0x08;
    uint256 constant V2_SWAP_EXACT_OUT = 0x09;
    uint256 constant PERMIT2_PERMIT = 0x0a;
    uint256 constant WRAP_ETH = 0x0b;
    uint256 constant UNWRAP_WETH = 0x0c;
    uint256 constant PERMIT2_TRANSFER_FROM_BATCH = 0x0d;
    uint256 constant BALANCE_CHECK_ERC20 = 0x0e;
    // COMMAND_PLACEHOLDER = 0x0f;

    // Command Types where 0x10<=value<=0x20, executed in the third nested-if block
    uint256 constant V4_SWAP = 0x10;
    uint256 constant V3_POSITION_MANAGER_PERMIT = 0x11;
    uint256 constant V3_POSITION_MANAGER_CALL = 0x12;
    uint256 constant V4_INITIALIZE_POOL = 0x13;
    uint256 constant V4_POSITION_MANAGER_CALL = 0x14;
    // COMMAND_PLACEHOLDER = 0x15 -> 0x20

    // Command Types where 0x21<=value<=0x3f
    uint256 constant EXECUTE_SUB_PLAN = 0x21;
    // COMMAND_PLACEHOLDER for 0x22 to 0x3f
}

// lib/v4-core/src/libraries/CustomRevert.sol

/// @title Library for reverting with custom errors efficiently
/// @notice Contains functions for reverting with custom errors with different argument types efficiently
/// @dev To use this library, declare `using CustomRevert for bytes4;` and replace `revert CustomError()` with
/// `CustomError.selector.revertWith()`
/// @dev The functions may tamper with the free memory pointer but it is fine since the call context is exited immediately
library CustomRevert {
    /// @dev ERC-7751 error for wrapping bubbled up reverts
    error WrappedError(address target, bytes4 selector, bytes reason, bytes details);

    /// @dev Reverts with the selector of a custom error in the scratch space
    function revertWith(bytes4 selector) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            revert(0, 0x04)
        }
    }

    /// @dev Reverts with a custom error with an address argument in the scratch space
    function revertWith(bytes4 selector, address addr) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            mstore(0x04, and(addr, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(0, 0x24)
        }
    }

    /// @dev Reverts with a custom error with an int24 argument in the scratch space
    function revertWith(bytes4 selector, int24 value) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            mstore(0x04, signextend(2, value))
            revert(0, 0x24)
        }
    }

    /// @dev Reverts with a custom error with a uint160 argument in the scratch space
    function revertWith(bytes4 selector, uint160 value) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            mstore(0x04, and(value, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(0, 0x24)
        }
    }

    /// @dev Reverts with a custom error with two int24 arguments
    function revertWith(bytes4 selector, int24 value1, int24 value2) internal pure {
        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(fmp, selector)
            mstore(add(fmp, 0x04), signextend(2, value1))
            mstore(add(fmp, 0x24), signextend(2, value2))
            revert(fmp, 0x44)
        }
    }

    /// @dev Reverts with a custom error with two uint160 arguments
    function revertWith(bytes4 selector, uint160 value1, uint160 value2) internal pure {
        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(fmp, selector)
            mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(fmp, 0x44)
        }
    }

    /// @dev Reverts with a custom error with two address arguments
    function revertWith(bytes4 selector, address value1, address value2) internal pure {
        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(fmp, selector)
            mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(fmp, 0x44)
        }
    }

    /// @notice bubble up the revert message returned by a call and revert with a wrapped ERC-7751 error
    /// @dev this method can be vulnerable to revert data bombs
    function bubbleUpAndRevertWith(
        address revertingContract,
        bytes4 revertingFunctionSelector,
        bytes4 additionalContext
    ) internal pure {
        bytes4 wrappedErrorSelector = WrappedError.selector;
        assembly ("memory-safe") {
            // Ensure the size of the revert data is a multiple of 32 bytes
            let encodedDataSize := mul(div(add(returndatasize(), 31), 32), 32)

            let fmp := mload(0x40)

            // Encode wrapped error selector, address, function selector, offset, additional context, size, revert reason
            mstore(fmp, wrappedErrorSelector)
            mstore(add(fmp, 0x04), and(revertingContract, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(
                add(fmp, 0x24),
                and(revertingFunctionSelector, 0xffffffff00000000000000000000000000000000000000000000000000000000)
            )
            // offset revert reason
            mstore(add(fmp, 0x44), 0x80)
            // offset additional context
            mstore(add(fmp, 0x64), add(0xa0, encodedDataSize))
            // size revert reason
            mstore(add(fmp, 0x84), returndatasize())
            // revert reason
            returndatacopy(add(fmp, 0xa4), 0, returndatasize())
            // size additional context
            mstore(add(fmp, add(0xa4, encodedDataSize)), 0x04)
            // additional context
            mstore(
                add(fmp, add(0xc4, encodedDataSize)),
                and(additionalContext, 0xffffffff00000000000000000000000000000000000000000000000000000000)
            )
            revert(fmp, add(0xe4, encodedDataSize))
        }
    }
}

// lib/solmate/src/tokens/ERC20.sol

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

// lib/openzeppelin-contracts/contracts/utils/Errors.sol

// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)

/**
 * @dev Collection of common custom errors used in multiple contracts
 *
 * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
 * It is recommended to avoid relying on the error API for critical functionality.
 *
 * _Available since v5.1._
 */
library Errors {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error InsufficientBalance(uint256 balance, uint256 needed);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedCall();

    /**
     * @dev The deployment failed.
     */
    error FailedDeployment();

    /**
     * @dev A necessary precompile is missing.
     */
    error MissingPrecompile(address);
}

// lib/v3-core/contracts/libraries/FixedPoint96.sol

/// @title FixedPoint96
/// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format)
/// @dev Used in SqrtPriceMath.sol
library FixedPoint96 {
    uint8 internal constant RESOLUTION = 96;
    uint256 internal constant Q96 = 0x1000000000000000000000000;
}

// lib/solmate/src/utils/FixedPointMathLib.sol

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant MAX_UINT256 = 2**256 - 1;

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // Divide x * y by the denominator.
            z := div(mul(x, y), denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // If x * y modulo the denominator is strictly greater than 0,
            // 1 is added to round up the division of x * y by the denominator.
            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            let y := x // We start y at x, which will help us make our initial estimate.

            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // We check y >= 2^(k + 8) but shift right by k bits
            // each branch to ensure that if x >= 256, then y >= 256.
            if iszero(lt(y, 0x10000000000000000000000000000000000)) {
                y := shr(128, y)
                z := shl(64, z)
            }
            if iszero(lt(y, 0x1000000000000000000)) {
                y := shr(64, y)
                z := shl(32, z)
            }
            if iszero(lt(y, 0x10000000000)) {
                y := shr(32, y)
                z := shl(16, z)
            }
            if iszero(lt(y, 0x1000000)) {
                y := shr(16, y)
                z := shl(8, z)
            }

            // Goal was to get z*z*y within a small factor of x. More iterations could
            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).
            // We ensured y >= 256 so that the relative difference between y and y+1 is small.
            // That's not possible if x < 256 but we can just verify those cases exhaustively.

            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.

            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.

            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.

            // There is no overflow risk here since y < 2^136 after the first branch above.
            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // If x+1 is a perfect square, the Babylonian method cycles between
            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.
            z := sub(z, lt(div(x, z), z))
        }
    }

    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Mod x by y. Note this will return
            // 0 instead of reverting if y is zero.
            z := mod(x, y)
        }
    }

    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Divide x by y. Note this will return
            // 0 instead of reverting if y is zero.
            r := div(x, y)
        }
    }

    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Add 1 to x * y if x % y > 0. Note this will
            // return 0 instead of reverting if y is zero.
            z := add(gt(mod(x, y), 0), div(x, y))
        }
    }
}

// lib/v3-core/contracts/libraries/FullMath.sol

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath_0 {
    /// @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 = (0 - denominator) & denominator;
            // 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++;
            }
        }
    }
}

// lib/v4-core/src/libraries/FullMath.sol

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath_1 {
    /// @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 = a * b; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly ("memory-safe") {
                let mm := mulmod(a, b, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Make sure the result is less than 2**256.
            // Also prevents denominator == 0
            require(denominator > prod1);

            // Handle non-overflow cases, 256 by 256 division
            if (prod1 == 0) {
                assembly ("memory-safe") {
                    result := div(prod0, denominator)
                }
                return result;
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0]
            // Compute remainder using mulmod
            uint256 remainder;
            assembly ("memory-safe") {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number
            assembly ("memory-safe") {
                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 = (0 - denominator) & denominator;
            // Divide denominator by power of two
            assembly ("memory-safe") {
                denominator := div(denominator, twos)
            }

            // Divide [prod1 prod0] by the factors of two
            assembly ("memory-safe") {
                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 ("memory-safe") {
                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 preconditions 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 > 0);
            }
        }
    }
}

// src/interfaces/IDatum.sol

interface IDatum {
    function getDatum() external view returns (uint256);
    function getDatumInDecimals(uint8 decimals) external view returns (uint256);
    function validateExchangeRateWithDatum(
        uint256 exchangeRate,
        uint8 exchangeRateDecimals,
        uint16 lowerBound,
        uint16 upperBound
    ) external view;
}

// lib/v4-periphery/lib/permit2/src/interfaces/IEIP712.sol

interface IEIP712 {
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// lib/v4-periphery/src/interfaces/IEIP712_v4.sol

/// @title IEIP712_v4
/// @notice Interface for the EIP712 contract
interface IEIP712_v4 {
    /// @notice Returns the domain separator for the current chain.
    /// @return bytes32 The domain separator
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol

// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// lib/v4-core/src/interfaces/external/IERC20Minimal.sol

/// @title Minimal ERC20 interface for Uniswap
/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3
interface IERC20Minimal {
    /// @notice Returns an account's balance in the token
    /// @param account The account for which to look up the number of tokens it has, i.e. its balance
    /// @return The number of tokens held by the account
    function balanceOf(address account) external view returns (uint256);

    /// @notice Transfers the amount of token from the `msg.sender` to the recipient
    /// @param recipient The account that will receive the amount transferred
    /// @param amount The number of tokens to send from the sender to the recipient
    /// @return Returns true for a successful transfer, false for an unsuccessful transfer
    function transfer(address recipient, uint256 amount) external returns (bool);

    /// @notice Returns the current allowance given to a spender by an owner
    /// @param owner The account of the token owner
    /// @param spender The account of the token spender
    /// @return The current allowance granted by `owner` to `spender`
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`
    /// @param spender The account which will be allowed to spend a given amount of the owners tokens
    /// @param amount The amount of tokens allowed to be used by `spender`
    /// @return Returns true for a successful approval, false for unsuccessful
    function approve(address spender, uint256 amount) external returns (bool);

    /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`
    /// @param sender The account from which the transfer will be initiated
    /// @param recipient The recipient of the transfer
    /// @param amount The amount of the transfer
    /// @return Returns true for a successful transfer, false for unsuccessful
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.
    /// @param from The account from which the tokens were sent, i.e. the balance decreased
    /// @param to The account to which the tokens were sent, i.e. the balance increased
    /// @param value The amount of tokens that were transferred
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.
    /// @param owner The account that approved spending of its tokens
    /// @param spender The account for which the spending allowance was modified
    /// @param value The new allowance from the owner to the spender
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// lib/v4-core/src/interfaces/external/IERC6909Claims.sol

/// @notice Interface for claims over a contract balance, wrapped as a ERC6909
interface IERC6909Claims {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OperatorSet(address indexed owner, address indexed operator, bool approved);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount);

    event Transfer(address caller, address indexed from, address indexed to, uint256 indexed id, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                                 FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Owner balance of an id.
    /// @param owner The address of the owner.
    /// @param id The id of the token.
    /// @return amount The balance of the token.
    function balanceOf(address owner, uint256 id) external view returns (uint256 amount);

    /// @notice Spender allowance of an id.
    /// @param owner The address of the owner.
    /// @param spender The address of the spender.
    /// @param id The id of the token.
    /// @return amount The allowance of the token.
    function allowance(address owner, address spender, uint256 id) external view returns (uint256 amount);

    /// @notice Checks if a spender is approved by an owner as an operator
    /// @...

// [truncated — 1008264 bytes total]

Read Contract

authority 0xbf7e214f → address
datum 0x4e47a3fe → address
datumLowerBound 0xdf1f9f8e → uint16
datumUpperBound 0xfaaf27d4 → uint16
getRate 0x37c59d6d → uint256
getRateSafe 0xa882e575 → uint256
hook 0x7f5a7c7b → address
isPaused 0xb187bd26 → bool
lastPerformanceReview 0xb777e0de → uint64
owner 0x8da5cb5b → address
payout 0x63bd1d4a → address
pendingFee 0x643090bc → uint128
performanceFee 0x87788782 → uint16
performanceReviewFrequency 0xc6719f8c → uint64
poolFee 0x089fe6aa → uint24
rebalanceDeviationMax 0xbcee6fb5 → uint16
rebalanceDeviationMin 0xef056ab9 → uint16
tickSpacing 0xd0c93a7c → int24
token0 0x0dfe1681 → address
token1 0xd21220a7 → address
totalAssets 0x351a3df1 → uint256
totalAssets 0x94605857 → uint256, uint256
trackedPositions 0x33d735d8 → uint256

Write Contract 12 functions

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

claimFees 0x1d416165
bool token0Or1
configureDatum 0xa70fc007
address _datum
uint16 _datumLowerBound
uint16 _datumUpperBound
pause 0x8456cb59
No parameters
rebalance 0x1f423d76
uint256 exchangeRate
tuple[] actions
refreshInternalFluxAccounting 0x33a9f811
No parameters
setAggregator 0xc1488069
address _aggregator
bool _isAggregator
setAuthority 0x7a9e5e4b
address newAuthority
setPayout 0xa3ff39b2
address newPayout
setPerformanceFee 0xaa290e6d
uint16 fee
setRebalanceDeviations 0x2f7409fc
uint16 min
uint16 max
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters

Recent Transactions

No transactions found for this address