diff --git a/foundry.toml b/foundry.toml index 3924e6689..2feb59f25 100644 --- a/foundry.toml +++ b/foundry.toml @@ -13,8 +13,9 @@ "SablierLockupDynamic", "SablierLockupLinear", "SablierLockupTranched", + "SablierMerkleFactory", + "SablierMerkleInstant", "SablierMerkleLL", - "SablierMerkleLockupFactory", "SablierMerkleLT", "SablierNFTDescriptor", ] diff --git a/precompiles/Precompiles.sol b/precompiles/Precompiles.sol index b62017fee..e84a317e9 100644 --- a/precompiles/Precompiles.sol +++ b/precompiles/Precompiles.sol @@ -8,7 +8,7 @@ import { ISablierLockupTranched } from "../src/core/interfaces/ISablierLockupTra import { ISablierNFTDescriptor } from "../src/core/interfaces/ISablierNFTDescriptor.sol"; import { SablierNFTDescriptor } from "../src/core/SablierNFTDescriptor.sol"; import { ISablierBatchLockup } from "../src/periphery/interfaces/ISablierBatchLockup.sol"; -import { ISablierMerkleLockupFactory } from "../src/periphery/interfaces/ISablierMerkleLockupFactory.sol"; +import { ISablierMerkleFactory } from "../src/periphery/interfaces/ISablierMerkleFactory.sol"; /// @notice This is useful for external integrations seeking to test against the exact deployed bytecode, as recompiling /// with via IR enabled would be time-consuming. @@ -28,7 +28,7 @@ contract Precompiles { hex"60a0604052346103bc57614b716040813803918261001c816103c0565b9384928339810103126103bc5780516001600160a01b03811691908290036103bc57602001516001600160a01b038116908190036103bc5761005e60406103c0565b91601983527f5361626c696572204c6f636b7570204c696e656172204e465400000000000000602084015261009360406103c0565b600e81526d29a0a116a627a1a5aaa816a624a760911b60208201523060805283519092906001600160401b0381116102cd57600154600181811c911680156103b2575b60208210146102af57601f811161034f575b50602094601f82116001146102ec579481929394955f926102e1575b50508160011b915f199060031b1c1916176001555b82516001600160401b0381116102cd57600254600181811c911680156102c3575b60208210146102af57601f811161024c575b506020601f82116001146101e957819293945f926101de575b50508160011b915f199060031b1c1916176002555b5f80546001600160a01b031990811684178255600880549091169290921790915560405191907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a3600160075561478b90816103e6823960805181613adf0152f35b015190505f80610165565b601f1982169060025f52805f20915f5b8181106102345750958360019596971061021c575b505050811b0160025561017a565b01515f1960f88460031b161c191690555f808061020e565b9192602060018192868b0151815501940192016101f9565b60025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace601f830160051c810191602084106102a5575b601f0160051c01905b81811061029a575061014c565b5f815560010161028d565b9091508190610284565b634e487b7160e01b5f52602260045260245ffd5b90607f169061013a565b634e487b7160e01b5f52604160045260245ffd5b015190505f80610104565b601f1982169560015f52805f20915f5b8881106103375750836001959697981061031f575b505050811b01600155610119565b01515f1960f88460031b161c191690555f8080610311565b919260206001819286850151815501940192016102fc565b60015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f830160051c810191602084106103a8575b601f0160051c01905b81811061039d57506100e8565b5f8155600101610390565b9091508190610387565b90607f16906100d6565b5f80fd5b6040519190601f01601f191682016001600160401b038111838210176102cd5760405256fe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a71461313b57508063027b67441461311957806306fdde031461305e578063081812fc14613040578063095ea7b314612f3b5780631400ecec14612e8a5780631c1cdd4c14612e265780631e99d56914612e0957806323b872dd14612df2578063303acc8514612db5578063406887cb14612c4657806340e58ee51461296f578063425d30dd1461291f57806342842e0e146128f657806342966c6814612732578063442675701461270c5780634857501f1461269b5780634869e12d146126615780634cc55e11146122ba57806353b157271461218f57806357404b12146120c95780636352211e1461209a5780636d0cee751461209a57806370a082311461203057806375829def14611fc2578063780a82c814611f765780637cad6cd114611e995780637de6b1db14611d4c5780638659c27014611994578063894e9a0d146116ac5780638f69b9931461162c5780639067b677146115dd57806395d89b41146114d5578063a22cb46514611421578063a80fc071146113d0578063ab167ccc1461125f578063ad35efd414611200578063b2564569146111b0578063b88d4fde14611126578063b8a3be66146110f1578063b971302a146110a3578063bc2be1be14611054578063c156a11d14610c3e578063c87b56dd14610b33578063d4dbd20b14610ae2578063d511609f14610a97578063d975dfed14610a4c578063e985e9c5146109f3578063ea5ead19146106ae578063eac8f5b81461065d578063f590c17614610601578063f851a440146105dc5763fdd46d6014610263575f80fd5b346105d85760603660031901126105d85760043561027f613268565b906102886133ca565b610290613ad5565b815f52600a60205260ff600160405f20015460a81c16156105c557815f52600a60205260ff600160405f20015460a01c166105b2576001600160a01b03831690811561059f576001600160801b031690811561058c57825f5260036020526001600160a01b0360405f20541693848214158061057c575b610561576001600160801b0361031c8561431f565b168084116105475750835f52600a60205282600260405f20015460801c016001600160801b0381116105335761037b90855f52600a602052600260405f2001906001600160801b036001600160801b031983549260801b169116179055565b835f52600a602052610392600260405f20016136ae565b6001600160801b036103b68160208401511692826040818351169201511690613402565b161115610501575b835f52600a6020526103e2836001600160a01b03600160405f200154169283614345565b81847f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051878152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051858152a183331415806104eb575b61044857005b604051926392b9102b60e01b84526004840152336024840152604483015260648201526020816084815f865af19081156104e0576392b9102b60e01b916001600160e01b0319915f916104b1575b50160361049f57005b636ade251160e01b5f5260045260245ffd5b6104d3915060203d6020116104d9575b6104cb818361338c565b8101906137e4565b5f610496565b503d6104c1565b6040513d5f823e3d90fd5b50835f52600960205260ff60405f205416610442565b5f848152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b191690556103be565b634e487b7160e01b5f52601160045260245ffd5b838563066920d760e01b5f5260045260245260445260645ffd5b508263350b320360e11b5f526004523360245260445260645ffd5b5061058684613b2f565b15610307565b8263b2ae763360e01b5f5260045260245ffd5b82632da33e5b60e01b5f5260045260245ffd5b506315efa0f360e11b5f5260045260245ffd5b5063699d2de960e01b5f5260045260245ffd5b5f80fd5b346105d8575f3660031901126105d85760206001600160a01b035f5416604051908152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a602052602060405f205460f81c6040519015158152f35b63699d2de960e01b5f5260045260245ffd5b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a60205260206001600160a01b03600160405f20015416604051908152f35b346105d85760403660031901126105d8576004356106ca613268565b906106d48161431f565b906106dd613ad5565b805f52600a60205260ff600160405f20015460a81c161561064b57805f52600a60205260ff600160405f20015460a01c166109e1576001600160a01b0383169182156109ce576001600160801b03169182156109bb57815f5260036020526001600160a01b0360405f2054169384821415806109ab575b610990576001600160801b036107698461431f565b168085116109765750825f52600a60205283600260405f20015460801c016001600160801b038111610533576107c890845f52600a602052600260405f2001906001600160801b036001600160801b031983549260801b169116179055565b825f52600a6020526107df600260405f20016136ae565b6001600160801b036108038160208401511692826040818351169201511690613402565b161115610944575b825f52600a60205261082f846001600160a01b03600160405f200154169283614345565b81837f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051888152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051848152a1833314158061092e575b61089f575b602083604051908152f35b604051916392b9102b60e01b8352600483015233602483015260448201528160648201526020816084815f875af19081156104e0576392b9102b60e01b916001600160e01b0319915f9161090f575b5016036108fc578180610894565b50636ade251160e01b5f5260045260245ffd5b610928915060203d6020116104d9576104cb818361338c565b856108ee565b50835f52600960205260ff60405f20541661088f565b5f838152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b1916905561080b565b848463066920d760e01b5f5260045260245260445260645ffd5b509063350b320360e11b5f526004523360245260445260645ffd5b506109b583613b2f565b15610754565b5063b2ae763360e01b5f5260045260245ffd5b50632da33e5b60e01b5f5260045260245ffd5b6315efa0f360e11b5f5260045260245ffd5b346105d85760403660031901126105d857610a0c613252565b6001600160a01b03610a1c613268565b91165f5260066020526001600160a01b0360405f2091165f52602052602060ff60405f2054166040519015158152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b57610a8660209161431f565b6001600160801b0360405191168152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a6020526020600260405f20015460801c604051908152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a60205260206001600160801b03600360405f20015416604051908152f35b346105d85760203660031901126105d857600435610b5081613804565b505f6001600160a01b0360085416916044604051809481937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa80156104e0575f90610bc1575b610bbd9060405191829160208352602083019061322d565b0390f35b503d805f833e610bd1818361338c565b8101906020818303126105d85780519067ffffffffffffffff82116105d857019080601f830112156105d857815191610c09836133ae565b91610c17604051938461338c565b838352602084830101116105d857610bbd92610c39916020808501910161320c565b610ba5565b346105d85760403660031901126105d857600435610c5a613268565b610c62613ad5565b815f52600a60205260ff600160405f20015460a81c16156105c557815f5260036020526001600160a01b0360405f2054169081330361103d576001600160801b03610cac8461431f565b169081158015610d35575b506001600160a01b03811615610d2257610cd9846001600160a01b039261399b565b169182610cf35783637e27328960e01b5f5260045260245ffd5b8084918403610d0757602083604051908152f35b9091506364283d7b60e01b5f5260045260245260445260645ffd5b633250574960e11b5f525f60045260245ffd5b610d3d613ad5565b845f52600a60205260ff600160405f20015460a81c161561102a57845f52600a60205260ff600160405f20015460a01c1661101757831561100457610ff157835f5260036020526001600160a01b0360405f2054168084141580610fe1575b610fc6576001600160801b03610db18661431f565b16808411610fac5750845f52600a60205282600260405f20015460801c016001600160801b03811161053357610e1090865f52600a602052600260405f2001906001600160801b036001600160801b031983549260801b169116179055565b845f52600a602052610e27600260405f20016136ae565b6001600160801b03610e4b8160208401511692826040818351169201511690613402565b161115610f7a575b845f52600a6020526001600160a01b03600160405f20015416610e77848683614345565b84867f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051888152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051878152a18033141580610f64575b15610cb7576040516392b9102b60e01b81528560048201523360248201528460448201528360648201526020816084815f865af19081156104e0576392b9102b60e01b916001600160e01b0319915f91610f45575b501614610cb757636ade251160e01b5f5260045260245ffd5b610f5e915060203d6020116104d9576104cb818361338c565b88610f2c565b50805f52600960205260ff60405f205416610ed7565b5f858152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b19169055610e53565b838663066920d760e01b5f5260045260245260445260645ffd5b838563350b320360e11b5f526004523360245260445260645ffd5b50610feb85613b2f565b15610d9c565b8363b2ae763360e01b5f5260045260245ffd5b84632da33e5b60e01b5f5260045260245ffd5b846315efa0f360e11b5f5260045260245ffd5b8463699d2de960e01b5f5260045260245ffd5b82632082501160e01b5f526004523360245260445ffd5b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a602052602064ffffffffff60405f205460a01c16604051908152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a60205260206001600160a01b0360405f205416604051908152f35b346105d85760203660031901126105d8576004355f52600a602052602060ff600160405f20015460a81c166040519015158152f35b346105d85760803660031901126105d85761113f613252565b611147613268565b6064359167ffffffffffffffff83116105d857366023840112156105d857826004013591611174836133ae565b92611182604051948561338c565b80845236602482870101116105d8576020815f9260246111ae98018388013785010152604435916136f4565b005b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a602052602060ff600160405f20015460b01c166040519015158152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b5761123890613907565b604051600582101561124b576020918152f35b634e487b7160e01b5f52602160045260245ffd5b346105d8576101403660031901126105d857611279613ad5565b611281613690565b64ffffffffff421680825264ffffffffff61129a6136e0565b166113b5575b60e43564ffffffffff811681036105d85764ffffffffff9101166040820152600435906001600160a01b038216918281036105d857506024356001600160a01b038116908181036105d857506044356001600160801b038116908181036105d857506064356001600160a01b0381168091036105d85760843591821515928381036105d8575060a43593841515948581036105d8575060405196611343886132e9565b8752602087015260408601526060850152608084015260a083015260c08201526040610103193601126105d8576040519061137d82613370565b61010435906001600160a01b03821682036105d857826113ad9260209452610124358482015260e0820152613c25565b604051908152f35b64ffffffffff6113c36136e0565b82011660208301526112a0565b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a60205260206001600160801b03600260405f20015416604051908152f35b346105d85760403660031901126105d85761143a613252565b602435908115158092036105d8576001600160a01b03169081156114a957335f52600660205260405f20825f5260205260405f2060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b507f5b08ba18000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346105d8575f3660031901126105d8576040515f6002548060011c906001811680156115d3575b6020831081146115bf5782855290811561159b575060011461153d575b610bbd836115298185038261338c565b60405191829160208352602083019061322d565b91905060025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace915f905b80821061158157509091508101602001611529611519565b919260018160209254838588010152019101909291611569565b60ff191660208086019190915291151560051b840190910191506115299050611519565b634e487b7160e01b5f52602260045260245ffd5b91607f16916114fc565b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a602052602064ffffffffff60405f205460c81c16604051908152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b5761166490613907565b60058110158061124b57600282149081156116a0575b811561168e575b6020826040519015158152f35b905061124b5760046020911482611681565b5050600381145f61167a565b346105d85760203660031901126105d8576004355f6101606040516116d081613336565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152611713613690565b6101408201520152805f52600a60205260ff600160405f20015460a81c161561064b57805f52600a60205260405f2060405161174e81613353565b81546001600160a01b0381168252602082019364ffffffffff8260a01c168552604083019364ffffffffff8360c81c1685526060840160ff8460f01c1615158152608085019360f81c1515845260018201549360a08601956001600160a01b038616875260c081019560ff8160a01c16151587526117ed600260e084019660ff8460a81c161515885260ff61010086019460b01c1615158452016136ae565b61012083019081526117fe87613907565b600581101561124b5760021461198c575b5197516001600160a01b031692865f52600b60205260405f205464ffffffffff16995164ffffffffff1694511515915115159751151595511515965f52600360205260405f20546001600160a01b031692516001600160a01b03169a5164ffffffffff16905115159260405161188481613336565b8c81526020810191825260408101928352606081019384526080810194855260a0810195865260c0810196875260e0810197885261010081019889526101208101998a5261014081019a8b52610160019a8b526040519b8c52516001600160a01b031660208c01525164ffffffffff1660408b015251151560608a01525115156080890152516001600160a01b031660a08801525164ffffffffff1660c087015251151560e08601525115156101008501525115156101208401525180516001600160801b031661014084015260208101516001600160801b0316610160840152604001516001600160801b03166101808301525164ffffffffff166101a08201526101c090f35b5f855261180f565b346105d85760203660031901126105d85760043567ffffffffffffffff81116105d8576119c59036906004016132b8565b906119ce613ad5565b5f915b8083106119da57005b6119e583828461366c565b35926119ef613ad5565b835f52600a60205260ff600160405f20015460a81c1615611d3957835f52600a60205260ff600160405f20015460a01c165f14611a3957836315efa0f360e11b5f5260045260245ffd5b909192805f52600a60205260405f205460f81c611d2757611a6e815f52600a6020526001600160a01b0360405f205416331490565b15611d1157611a7c81613825565b90805f52600a602052611a94600260405f20016136ae565b916001600160801b038351166001600160801b0382161015611cfe57815f52600a60205260ff60405f205460f01c1615611ceb57806001600160801b03602081611ae8948188511603169501511690613402565b5f828152600a6020526040902080547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b179055916001600160801b038316908115611cc6575b825f52600a602052600360405f20016001600160801b0382166001600160801b0319825416179055825f52600a6020526001600160a01b0360405f205416835f5260036020526001600160a01b0360405f20541694845f52600a60205285827f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa50611bfa6001600160a01b03600160405f2001541694611bd2888588614345565b604080518b81526001600160801b03808b166020830152909216908201529081906060820190565b0390a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051868152a1845f52600960205260ff60405f205416611c4b575b505050505060010191906119d1565b60405193630d4af11f60e31b855260048501526024840152604483015260648201526020816084815f865af19081156104e057630d4af11f60e31b916001600160e01b0319915f91611ca8575b50160361049f5780808080611c3c565b611cc0915060203d81116104d9576104cb818361338c565b87611c98565b825f52600a602052600160405f2001600160a01b60ff60a01b19825416179055611b32565b50635dd950cb60e11b5f5260045260245ffd5b506308aca53f60e21b5f5260045260245ffd5b632082501160e01b5f526004523360245260445ffd5b63d0a172b360e01b5f5260045260245ffd5b8363699d2de960e01b5f5260045260245ffd5b346105d85760203660031901126105d857600435611d68613ad5565b805f52600a60205260ff600160405f20015460a81c161561064b57611d8c81613907565b600581101561124b5760048103611db057506315efa0f360e11b5f5260045260245ffd5b60038103611dcb575063d0a172b360e01b5f5260045260245ffd5b600214611e8757611df0815f52600a6020526001600160a01b0360405f205416331490565b15611d1157805f52600a60205260ff60405f205460f01c1615611e75576020817ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7925f52600a825260405f2060ff60f01b19815416905560405190807f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f5f80a28152a1005b635dd950cb60e11b5f5260045260245ffd5b6308aca53f60e21b5f5260045260245ffd5b346105d85760203660031901126105d8576004356001600160a01b0381168091036105d8576001600160a01b035f5416338103611f60575060085490806001600160a01b03198316176008556001600160a01b036040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a26007545f1981019081116105335760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a1005b6331b339a960e21b5f526004523360245260445ffd5b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600b602052602064ffffffffff60405f205416604051908152f35b346105d85760203660031901126105d857611fdb613252565b5f546001600160a01b038116338103611f6057506001600160a01b036001600160a01b0319921691829116175f55337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf805f80a3005b346105d85760203660031901126105d8576001600160a01b03612051613252565b16801561206e575f526004602052602060405f2054604051908152f35b7f89c62b64000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b346105d85760203660031901126105d85760206120b8600435613804565b6001600160a01b0360405191168152f35b346105d85760203660031901126105d8576004356120e5613690565b50805f52600a60205260ff600160405f20015460a81c161561064b57806060915f52600a60205264ffffffffff60405f205460a01c1690805f52600b60205264ffffffffff60405f205416905f52600a60205264ffffffffff60405f205460c81c1690604051926121558461331a565b83526020830152604082015261218d604051809264ffffffffff60408092828151168552826020820151166020860152015116910152565bf35b346105d8576101603660031901126105d8576121a9613ad5565b6040516121b5816132e9565b6121bd613252565b81526121c7613268565b60208201526121d46133ca565b60408201526064356001600160a01b03811681036105d857606082015260843580151581036105d857608082015260a43580151581036105d85760a082015260603660c31901126105d85760405161222b8161331a565b60c43564ffffffffff811681036105d857815260e43564ffffffffff811681036105d85760208201526101043564ffffffffff811681036105d857604082015260c08201526040610123193601126105d8576040519061228a82613370565b61012435906001600160a01b03821682036105d857826113ad9260209452610144358482015260e0820152613c25565b346105d85760403660031901126105d85760043567ffffffffffffffff81116105d8576122eb9036906004016132b8565b60243567ffffffffffffffff81116105d85761230b9036906004016132b8565b612316939193613ad5565b808303612632575f5b83811061232857005b61233381858561366c565b3561233f82868661366c565b355f5260036020526001600160a01b0360405f2054169061236183858961366c565b356001600160801b038116908181036105d8575061237d613ad5565b815f52600a60205260ff600160405f20015460a81c16156105c557815f52600a60205260ff600160405f20015460a01c166105b25782156109ce5780156109bb57815f5260036020526001600160a01b0360405f205416928381141580612622575b612608576001600160801b036123f48461431f565b168083116125ee5750825f52600a60205281600260405f20015460801c016001600160801b0381116105335761245390845f52600a602052600260405f2001906001600160801b036001600160801b031983549260801b169116179055565b825f52600a60205261246a600260405f20016136ae565b6001600160801b0361248e8160208401511692826040818351169201511690613402565b1611156125bc575b825f52600a6020526001600160a01b03600160405f200154166124ba838383614345565b81847f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051878152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051858152a183331415806125a6575b61252b575b5050505060010161231f565b604051926392b9102b60e01b84526004840152336024840152604483015260648201526020816084815f865af19081156104e0576392b9102b60e01b916001600160e01b0319915f91612588575b50160361049f5780808061251f565b6125a0915060203d81116104d9576104cb818361338c565b89612579565b50835f52600960205260ff60405f20541661251a565b5f838152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b19169055612496565b828463066920d760e01b5f5260045260245260445260645ffd5b8263350b320360e11b5f526004523360245260445260645ffd5b5061262c83613b2f565b156123df565b827fa5ed43e6000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b57610a86602091613ba1565b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f6126d482613907565b600581101561124b576002036126f2575b6020906040519015158152f35b505f52600a602052602060ff60405f205460f01c166126e5565b346105d8575f3660031901126105d85760206001600160a01b0360085416604051908152f35b346105d85760203660031901126105d85760043561274e613ad5565b805f52600a60205260ff600160405f20015460a81c161561064b57805f52600a60205260ff600160405f20015460a01c16156128cb5761278d81613b2f565b15611d1157805f5260036020526001600160a01b0360405f2054161515806128c4575b806128a7575b612895577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051838152a1805f5260036020526001600160a01b0360405f205416801590811561285e575b825f52600360205260405f206001600160a01b03198154169055825f827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a45061284c57005b637e27328960e01b5f5260045260245ffd5b61287d835f52600560205260405f206001600160a01b03198154169055565b805f52600460205260405f205f198154019055612804565b634274c8e160e11b5f5260045260245ffd5b50805f52600a60205260ff600160405f20015460b01c16156127b6565b505f6127b0565b7f6121eb36000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346105d8576111ae6129073661327e565b906040519261291760208561338c565b5f84526136f4565b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b575f52600a602052602060ff600160405f20015460a01c166040519015158152f35b346105d85760203660031901126105d85760043561298b613ad5565b805f52600a60205260ff600160405f20015460a81c161561064b57805f52600a60205260ff600160405f20015460a01c165f146129d4576315efa0f360e11b5f5260045260245ffd5b805f52600a60205260405f205460f81c611d2757612a06815f52600a6020526001600160a01b0360405f205416331490565b15611d1157612a1481613825565b90805f52600a602052612a2c600260405f20016136ae565b916001600160801b038351166001600160801b0382161015611cfe57815f52600a60205260ff60405f205460f01c1615611ceb57806001600160801b03602081612a80948188511603169501511690613402565b5f828152600a6020526040902080547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b179055916001600160801b038316908115612c21575b825f52600a602052600360405f20016001600160801b0382166001600160801b0319825416179055825f52600a6020526001600160a01b0360405f205416835f5260036020526001600160a01b0360405f20541694845f52600a60205285827f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa50612b6a6001600160a01b03600160405f2001541694611bd2888588614345565b0390a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051868152a1845f52600960205260ff60405f205416612bad57005b60405193630d4af11f60e31b855260048501526024840152604483015260648201526020816084815f865af19081156104e057630d4af11f60e31b916001600160e01b0319915f91612c025750160361049f57005b612c1b915060203d6020116104d9576104cb818361338c565b84610496565b825f52600a602052600160405f2001600160a01b60ff60a01b19825416179055612aca565b346105d85760203660031901126105d857612c5f613252565b6001600160a01b035f541690338203612d9e57806001600160a01b03913b15612d7257166040516301ffc9a760e01b81527ff8ee98d3000000000000000000000000000000000000000000000000000000006004820152602081602481855afa9081156104e0575f91612d43575b5015612d1857805f52600960205260405f20600160ff198254161790556040519081527fb4378d4e289cb3f40f4f75a99c9cafa76e3df1c4dc31309babc23dc91bd7280160203392a2005b7ff1dc125d000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b612d65915060203d602011612d6b575b612d5d818361338c565b810190613654565b82612ccd565b503d612d53565b7f295097c8000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b506331b339a960e21b5f526004523360245260445ffd5b346105d85760203660031901126105d8576001600160a01b03612dd6613252565b165f526009602052602060ff60405f2054166040519015158152f35b346105d8576111ae612e033661327e565b91613422565b346105d8575f3660031901126105d8576020600754604051908152f35b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b57612e5e90613907565b600581101561124b578060209115908115612e7f575b506040519015158152f35b600191501482612e74565b346105d85760203660031901126105d857600435805f52600a60205260ff600160405f20015460a81c161561064b576020905f90805f52600a835260ff60405f205460f01c1680612f1f575b612eed575b506001600160801b0360405191168152f35b612f199150805f52600a8352612f136001600160801b03600260405f2001541691613825565b90613402565b82612edb565b50805f52600a835260ff600160405f20015460a01c1615612ed6565b346105d85760403660031901126105d857612f54613252565b602435612f6081613804565b3315158061302d575b80612ffa575b612fce5781906001600160a01b0380851691167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a45f5260056020526001600160a01b0360405f2091166001600160a01b03198254161790555f80f35b7fa9fbf51f000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b506001600160a01b0381165f52600660205260405f206001600160a01b0333165f5260205260ff60405f20541615612f6f565b50336001600160a01b0382161415612f69565b346105d85760203660031901126105d85760206120b86004356133e0565b346105d8575f3660031901126105d8576040515f6001548060011c9060018116801561310f575b6020831081146115bf5782855290811561159b57506001146130b157610bbd836115298185038261338c565b91905060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6915f905b8082106130f557509091508101602001611529611519565b9192600181602092548385880101520191019092916130dd565b91607f1691613085565b346105d8575f3660031901126105d857602060405167016345785d8a00008152f35b346105d85760203660031901126105d857600435906001600160e01b031982168092036105d857817f490649060000000000000000000000000000000000000000000000000000000060209314908115613197575b5015158152f35b7f80ac58cd000000000000000000000000000000000000000000000000000000008114915081156131e2575b81156131d1575b5083613190565b6301ffc9a760e01b915014836131ca565b7f5b5e139f00000000000000000000000000000000000000000000000000000000811491506131c3565b5f5b83811061321d5750505f910152565b818101518382015260200161320e565b906020916132468151809281855285808601910161320c565b601f01601f1916010190565b600435906001600160a01b03821682036105d857565b602435906001600160a01b03821682036105d857565b60609060031901126105d8576004356001600160a01b03811681036105d857906024356001600160a01b03811681036105d8579060443590565b9181601f840112156105d85782359167ffffffffffffffff83116105d8576020808501948460051b0101116105d857565b610100810190811067ffffffffffffffff82111761330657604052565b634e487b7160e01b5f52604160045260245ffd5b6060810190811067ffffffffffffffff82111761330657604052565b610180810190811067ffffffffffffffff82111761330657604052565b610140810190811067ffffffffffffffff82111761330657604052565b6040810190811067ffffffffffffffff82111761330657604052565b90601f8019910116810190811067ffffffffffffffff82111761330657604052565b67ffffffffffffffff811161330657601f01601f191660200190565b604435906001600160801b03821682036105d857565b6133e981613804565b505f5260056020526001600160a01b0360405f20541690565b906001600160801b03809116911603906001600160801b03821161053357565b91906001600160a01b03168015610d2257815f5260036020526001600160a01b0360405f20541615158061364c575b8061362f575b61361c577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051848152a1815f5260036020526001600160a01b0360405f20541692823315159283613567575b6001600160a01b03935085613530575b805f52600460205260405f2060018154019055815f52600360205260405f20816001600160a01b0319825416179055857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a41680830361351857505050565b6364283d7b60e01b5f5260045260245260445260645ffd5b61354f825f52600560205260405f206001600160a01b03198154169055565b855f52600460205260405f205f1981540190556134b7565b91929050806135c5575b1561357e578282916134a7565b828461359657637e27328960e01b5f5260045260245ffd5b7f177e802f000000000000000000000000000000000000000000000000000000005f523360045260245260445ffd5b5033841480156135f3575b806135715750825f526005602052336001600160a01b0360405f20541614613571565b50835f52600660205260405f206001600160a01b0333165f5260205260ff60405f2054166135d0565b50634274c8e160e11b5f5260045260245ffd5b50815f52600a60205260ff600160405f20015460b01c1615613457565b506001613451565b908160209103126105d8575180151581036105d85790565b919081101561367c5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b6040519061369d8261331a565b5f6040838281528260208201520152565b906040516136bb8161331a565b60406001600160801b03600183958054838116865260801c6020860152015416910152565b60c43564ffffffffff811681036105d85790565b90613700838284613422565b803b61370d575b50505050565b6020916137536001600160a01b03809316956040519586948594630a85bd0160e11b8652336004870152166024850152604484015260806064840152608483019061322d565b03815f865af15f91816137c3575b5061378f575061376f6142f0565b8051908161378a5782633250574960e11b5f5260045260245ffd5b602001fd5b6001600160e01b0319630a85bd0160e11b9116036137b157505f808080613707565b633250574960e11b5f5260045260245ffd5b6137dd91925060203d6020116104d9576104cb818361338c565b905f613761565b908160209103126105d857516001600160e01b0319811681036105d85790565b805f5260036020526001600160a01b0360405f20541690811561284c575090565b805f52600b60205264ffffffffff60405f205416815f52600a60205264ffffffffff60405f205460a01c1690421080156138fd575b6138f757815f52600a60205264ffffffffff60405f205460c81c1690814210156138da578061388c92039042036144d3565b815f52600a6020526138af6001600160801b03600260405f2001541680926145bf565b9081116138c4576001600160801b0391501690565b505f52600a602052600260405f20015460801c90565b50505f52600a6020526001600160801b03600260405f2001541690565b50505f90565b504281101561385a565b805f52600a60205260ff600160405f20015460a01c165f146139295750600490565b805f52600a60205260405f205460f81c61399557805f52600a60205264ffffffffff60405f205460a01c1642106139905761396381613825565b905f52600a6020526001600160801b0380600260405f200154169116105f1461398b57600190565b600290565b505f90565b50600390565b90805f5260036020526001600160a01b0360405f205416151580613ac3575b80613aa6575b612895577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051838152a1805f5260036020526001600160a01b038060405f2054169283613a6f575b1680613a57575b815f52600360205260405f20816001600160a01b0319825416179055827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a490565b805f52600460205260405f2060018154019055613a13565b613a8e835f52600560205260405f206001600160a01b03198154169055565b835f52600460205260405f205f198154019055613a0c565b50805f52600a60205260ff600160405f20015460b01c16156139c0565b506001600160a01b03821615156139ba565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003613b0757565b7fa1c0d6e5000000000000000000000000000000000000000000000000000000005f5260045ffd5b805f5260036020526001600160a01b0360405f20541690813314918215613b75575b508115613b5c575090565b90506001600160a01b03613b7033926133e0565b161490565b9091505f52600660205260405f206001600160a01b0333165f5260205260ff60405f205416905f613b51565b805f52600a602052613bb8600260405f20016136ae565b90805f52600a60205260ff600160405f20015460a01c165f14613be65750602001516001600160801b031690565b90815f52600a60205260405f205460f81c613c085750613c0590613825565b90565b613c0591506001600160801b036040818351169201511690613402565b90613c466001600160801b03604084015116602060e085015101519061439c565b916001600160801b0383511660c082015190156142c85764ffffffffff815116156142a0576020810164ffffffffff81511680614214575b5050604064ffffffffff82511691019064ffffffffff82511690818110156141e657505064ffffffffff80421691511690818110156141b85750506007549280516001600160801b03169160405192613cd68461331a565b8352602083015f9052604083015f905260608101516001600160a01b03169260c082015190604082015164ffffffffff16946080840195888751151560a087015115159287516001600160a01b0316965164ffffffffff169160405197613d3c89613353565b885260208801928352604088019182526060880190815260808801915f835260a0890196875260c08901935f855260e08a0195600187526101008b019788526101208b01998a525f52600a60205260405f2099516001600160a01b03166001600160a01b03168a546001600160a01b031916178a5551908954905160c81b7dffffffffff00000000000000000000000000000000000000000000000000169160a01b78ffffffffff000000000000000000000000000000000000000016907fffff00000000000000000000ffffffffffffffffffffffffffffffffffffffff161717885551151587549060f01b7eff000000000000000000000000000000000000000000000000000000000000169060ff60f01b191617875551151586549060f81b7fff0000000000000000000000000000000000000000000000000000000000000016907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff161786556001860193516001600160a01b03166001600160a01b031684546001600160a01b03191617845551151583549060a01b74ff0000000000000000000000000000000000000000169060ff60a01b19161783555115159082549051151560b01b76ff00000000000000000000000000000000000000000000169160a81b75ff00000000000000000000000000000000000000000016907fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff16171790556002820190519081516001600160801b03166001600160801b031681546001600160801b03191617815560208201516001600160801b0316613fbc91906001600160801b036001600160801b031983549260801b169116179055565b604001516001600160801b031690600301906001600160801b031681546001600160801b03191617905560c08101516020015164ffffffffff1680614198575b50600185016007556001600160a01b036020820151168015610d225761402a866001600160a01b039261399b565b1661416c576140556001600160a01b036060830151166001600160801b038451169030903390614479565b7f44cb432df42caa86b7ec73644ab8aec922bc44c71c98fc330addc75b88adbc7c6101408660208501946001600160801b038651168061413d575b506141346001600160a01b03865116956001600160a01b03602082015116976001600160a01b03606083015116995115156001600160801b0360a0840151151592816001600160a01b0360e060c0880151970151511697604051998a523360208b01525116604089015251166060870152608086015260a085015260c084019064ffffffffff60408092828151168552826020820151166020860152015116910152565b610120820152a4565b614166906001600160a01b036060880151166001600160a01b0360e08901515116903390614479565b5f614090565b7f73c6ac6e000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b855f52600b60205260405f209064ffffffffff198254161790555f613ffc565b7f879842de000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b7f9e7fd91f000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b64ffffffffff8351168181101561427257505064ffffffffff90511664ffffffffff60408301511690818110613c7e577f87d966a0000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b7f84fe0623000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b7feaa6c316000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f779f8816000000000000000000000000000000000000000000000000000000005f5260045ffd5b3d1561431a573d90614301826133ae565b9161430f604051938461338c565b82523d5f602084013e565b606090565b613c059061432c81613ba1565b905f52600a602052600260405f20015460801c90613402565b61439a926001600160a01b03604051937fa9059cbb00000000000000000000000000000000000000000000000000000000602086015216602484015260448301526044825261439560648361338c565b61466d565b565b9190916040516143ab81613370565b5f81525f6020820152926001600160801b03821690811561445c5767016345785d8a00008111614425576143e76001600160801b0391836145bf565b1660208501918183521115614411576001600160801b03918261440c92511690613402565b168252565b634e487b7160e01b5f52600160045260245ffd5b7ffc8a7df4000000000000000000000000000000000000000000000000000000005f5260045267016345785d8a000060245260445ffd5b505050905060405161446d81613370565b5f81525f602082015290565b9091926001600160a01b0361439a9481604051957f23b872dd00000000000000000000000000000000000000000000000000000000602088015216602486015216604484015260648301526064825261439560848361338c565b5f19670de0b6b3a7640000820991670de0b6b3a764000082029182808510940393808503941461459e578184101561456457670de0b6b3a7640000829109600182190182168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b7f63a05778000000000000000000000000000000000000000000000000000000005f52600452670de0b6b3a764000060245260445260645ffd5b50915081156145ab570490565b634e487b7160e01b5f52601260045260245ffd5b9091905f198382098382029182808310920391808303921461465c57670de0b6b3a764000082101561462c577faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106699394670de0b6b3a7640000910990828211900360ee1b910360121c170290565b84907f5173648d000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b5050670de0b6b3a764000090049150565b5f806001600160a01b0361469693169360208151910182865af161468f6142f0565b90836146f2565b80519081151591826146d7575b50506146ac5750565b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b6146ea9250602080918301019101613654565b155f806146a3565b9061472f575080511561470757805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b81511580614775575b614740575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b1561473856fea164736f6c634300081a000a"; bytes public constant BYTECODE_LOCKUP_TRANCHED = hex"60c0604052346103e157614e306060813803918261001c816103e5565b9384928339810103126103e15780516001600160a01b038116908190036103e15760208201516001600160a01b03811692908390036103e1576040015161006360406103e5565b92601b84527f5361626c696572204c6f636b7570205472616e63686564204e46540000000000602085015261009860406103e5565b600e81526d5341422d4c4f434b55502d54524160901b602082015230608052845190946001600160401b0382116102e45760015490600182811c921680156103d7575b60208310146102c65781601f849311610369575b50602090601f8311600114610303575f926102f8575b50508160011b915f199060031b1c1916176001555b83516001600160401b0381116102e457600254600181811c911680156102da575b60208210146102c657601f8111610263575b50602094601f8211600114610200579481929394955f926101f5575b50508160011b915f199060031b1c1916176002555b5f80546001600160a01b031990811685178255600880549091169290921790915560405192907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a360a0526001600755614a25908161040b823960805181613e37015260a051818181612fa60152613ee00152f35b015190505f80610169565b601f1982169560025f52805f20915f5b88811061024b57508360019596979810610233575b505050811b0160025561017e565b01515f1960f88460031b161c191690555f8080610225565b91926020600181928685015181550194019201610210565b60025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace601f830160051c810191602084106102bc575b601f0160051c01905b8181106102b1575061014d565b5f81556001016102a4565b909150819061029b565b634e487b7160e01b5f52602260045260245ffd5b90607f169061013b565b634e487b7160e01b5f52604160045260245ffd5b015190505f80610105565b60015f9081528281209350601f198516905b8181106103515750908460019594939210610339575b505050811b0160015561011a565b01515f1960f88460031b161c191690555f808061032b565b92936020600181928786015181550195019301610315565b60015f529091507fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f840160051c810191602085106103cd575b90601f859493920160051c01905b8181106103bf57506100ef565b5f81558493506001016103b2565b90915081906103a4565b91607f16916100db565b5f80fd5b6040519190601f01601f191682016001600160401b038111838210176102e45760405256fe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a71461331257508063027b6744146132f057806306fdde0314613235578063081812fc14613217578063095ea7b3146131125780631400ecec146130615780631c1cdd4c14612ffd5780631e99d56914612fe057806323b872dd14612fc95780632fe4304114612f8f578063303acc8514612f5257806332fbe22b14612df5578063406887cb14612c8657806340e58ee5146129af578063425d30dd1461295f57806342842e0e1461293657806342966c6814612772578063442675701461274c5780634857501f146126db5780634869e12d146126a15780634cc55e11146122fb57806357404b121461226d5780636352211e1461223e5780636d0cee751461223e57806370a08231146121d457806375829def146121665780637cad6cd1146120755780637de6b1db14611f285780637f5799f914611ecf5780638659c27014611b17578063894e9a0d146117d8578063897f362b1461150d5780638f69b9931461148d5780639067b6771461143e57806395d89b4114611336578063a22cb46514611282578063a80fc07114611231578063ad35efd4146111d2578063b256456914611182578063b88d4fde146110f8578063b8a3be66146110c3578063b971302a14611075578063bc2be1be14611026578063c156a11d14610c0a578063c87b56dd14610aff578063d4dbd20b14610aae578063d511609f14610a63578063d975dfed14610a18578063e985e9c5146109bf578063ea5ead1914610692578063eac8f5b814610641578063f590c176146105e5578063f851a440146105c05763fdd46d601461026e575f80fd5b346105bc5760603660031901126105bc5760043561028a61343f565b90604435916001600160801b038316908184036105bc576102a9613e2d565b825f52600a60205260ff600160405f20015460a81c16156105a957825f52600a60205260ff600160405f20015460a01c16610596576001600160a01b03811690811561058357821561057057835f5260036020526001600160a01b0360405f205416948583141580610560575b610545576001600160801b0361032b86614685565b1680851161052b575061035090855f52600a602052600260405f20015460801c6146ab565b5f858152600a6020526040902060020180546001600160801b031660809290921b6001600160801b03191691909117815561038a906139d3565b6001600160801b036103ae8160208401511692826040818351169201511690613616565b1611156104f9575b835f52600a6020526103da836001600160a01b03600160405f200154169283614809565b81847f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051878152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051858152a183331415806104e3575b61044057005b604051926392b9102b60e01b84526004840152336024840152604483015260648201526020816084815f865af19081156104d8576392b9102b60e01b916001600160e01b0319915f916104a9575b50160361049757005b636ade251160e01b5f5260045260245ffd5b6104cb915060203d6020116104d1575b6104c381836135a2565b810190613b16565b5f61048e565b503d6104b9565b6040513d5f823e3d90fd5b50835f52600960205260ff60405f20541661043a565b5f848152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b191690556103b6565b848663066920d760e01b5f5260045260245260445260645ffd5b828563350b320360e11b5f526004523360245260445260645ffd5b5061056a85614560565b15610316565b8363b2ae763360e01b5f5260045260245ffd5b83632da33e5b60e01b5f5260045260245ffd5b826315efa0f360e11b5f5260045260245ffd5b8263699d2de960e01b5f5260045260245ffd5b5f80fd5b346105bc575f3660031901126105bc5760206001600160a01b035f5416604051908152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a602052602060405f205460f81c6040519015158152f35b63699d2de960e01b5f5260045260245ffd5b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a60205260206001600160a01b03600160405f20015416604051908152f35b346105bc5760403660031901126105bc576004356106ae61343f565b6106b782614685565b916106c0613e2d565b805f52600a60205260ff600160405f20015460a81c161561062f57805f52600a60205260ff600160405f20015460a01c166109ad576001600160a01b038216801561099a576001600160801b03841692831561098757825f5260036020526001600160a01b0360405f205416948583141580610977575b61095c576001600160801b0361074c85614685565b16808611610942575061077190845f52600a602052600260405f20015460801c6146ab565b5f848152600a6020526040902060020180546001600160801b031660809290921b6001600160801b0319169190911781556107ab906139d3565b6001600160801b036107cf8160208401511692826040818351169201511690613616565b161115610910575b825f52600a6020526107fb846001600160a01b03600160405f200154169283614809565b81837f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051888152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051848152a183331415806108fa575b61086b575b602083604051908152f35b604051916392b9102b60e01b8352600483015233602483015260448201528160648201526020816084815f875af19081156104d8576392b9102b60e01b916001600160e01b0319915f916108db575b5016036108c8578180610860565b50636ade251160e01b5f5260045260245ffd5b6108f4915060203d6020116104d1576104c381836135a2565b856108ba565b50835f52600960205260ff60405f20541661085b565b5f838152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b191690556107d7565b858563066920d760e01b5f5260045260245260445260645ffd5b828463350b320360e11b5f526004523360245260445260645ffd5b5061098184614560565b15610737565b8263b2ae763360e01b5f5260045260245ffd5b50632da33e5b60e01b5f5260045260245ffd5b6315efa0f360e11b5f5260045260245ffd5b346105bc5760403660031901126105bc576109d8613429565b6001600160a01b036109e861343f565b91165f5260066020526001600160a01b0360405f2091165f52602052602060ff60405f2054166040519015158152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f57610a52602091614685565b6001600160801b0360405191168152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a6020526020600260405f20015460801c604051908152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a60205260206001600160801b03600360405f20015416604051908152f35b346105bc5760203660031901126105bc57600435610b1c81613b36565b505f6001600160a01b0360085416916044604051809481937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa80156104d8575f90610b8d575b610b8990604051918291602083526020830190613404565b0390f35b503d805f833e610b9d81836135a2565b8101906020818303126105bc5780519067ffffffffffffffff82116105bc57019080601f830112156105bc57815191610bd5836135c4565b91610be360405193846135a2565b838352602084830101116105bc57610b8992610c0591602080850191016133e3565b610b71565b346105bc5760403660031901126105bc57600435610c2661343f565b610c2e613e2d565b815f52600a60205260ff600160405f20015460a81c161561101357815f5260036020526001600160a01b0360405f20541690813303610ffc57610c7083614685565b906001600160801b0382169182158015610d04575b50506001600160a01b03811615610cf157610ca8846001600160a01b0392613cf3565b169182610cc25783637e27328960e01b5f5260045260245ffd5b8084918403610cd657602083604051908152f35b9091506364283d7b60e01b5f5260045260245260445260645ffd5b633250574960e11b5f525f60045260245ffd5b610d0c613e2d565b855f52600a60205260ff600160405f20015460a81c1615610fe957855f52600a60205260ff600160405f20015460a01c16610fd6578415610fc357610fb057845f5260036020526001600160a01b0360405f205416908185141580610fa0575b610f85576001600160801b03610d8187614685565b16808511610f6b5750610da690865f52600a602052600260405f20015460801c6146ab565b5f868152600a6020526040902060020180546001600160801b031660809290921b6001600160801b031916919091178155610de0906139d3565b6001600160801b03610e048160208401511692826040818351169201511690613616565b161115610f39575b845f52600a6020526001600160a01b03600160405f20015416610e30848683614809565b84867f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051888152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051878152a18033141580610f23575b610e9b575b80610c85565b6040516392b9102b60e01b81528560048201523360248201528460448201528360648201526020816084815f865af19081156104d8576392b9102b60e01b916001600160e01b0319915f91610f04575b501614610e9557636ade251160e01b5f5260045260245ffd5b610f1d915060203d6020116104d1576104c381836135a2565b88610eeb565b50805f52600960205260ff60405f205416610e90565b5f858152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b19169055610e0c565b848763066920d760e01b5f5260045260245260445260645ffd5b848663350b320360e11b5f526004523360245260445260645ffd5b50610faa86614560565b15610d6c565b8463b2ae763360e01b5f5260045260245ffd5b85632da33e5b60e01b5f5260045260245ffd5b856315efa0f360e11b5f5260045260245ffd5b8563699d2de960e01b5f5260045260245ffd5b82632082501160e01b5f526004523360245260445ffd5b5063699d2de960e01b5f5260045260245ffd5b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a602052602064ffffffffff60405f205460a01c16604051908152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a60205260206001600160a01b0360405f205416604051908152f35b346105bc5760203660031901126105bc576004355f52600a602052602060ff600160405f20015460a81c166040519015158152f35b346105bc5760803660031901126105bc57611111613429565b61111961343f565b6064359167ffffffffffffffff83116105bc57366023840112156105bc57826004013591611146836135c4565b9261115460405194856135a2565b80845236602482870101116105bc576020815f9260246111809801838801378501015260443591613a26565b005b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a602052602060ff600160405f20015460b01c166040519015158152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f5761120a90613c5f565b604051600582101561121d576020918152f35b634e487b7160e01b5f52602160045260245ffd5b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a60205260206001600160801b03600260405f20015416604051908152f35b346105bc5760403660031901126105bc5761129b613429565b602435908115158092036105bc576001600160a01b031690811561130a57335f52600660205260405f20825f5260205260405f2060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b507f5b08ba18000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346105bc575f3660031901126105bc576040515f6002548060011c90600181168015611434575b602083108114611420578285529081156113fc575060011461139e575b610b898361138a818503826135a2565b604051918291602083526020830190613404565b91905060025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace915f905b8082106113e25750909150810160200161138a61137a565b9192600181602092548385880101520191019092916113ca565b60ff191660208086019190915291151560051b8401909101915061138a905061137a565b634e487b7160e01b5f52602260045260245ffd5b91607f169161135d565b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a602052602064ffffffffff60405f205460c81c16604051908152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f576114c590613c5f565b60058110158061121d5760028214908115611501575b81156114ef575b6020826040519015158152f35b905061121d57600460209114826114e2565b5050600381145f6114db565b346105bc5760203660031901126105bc5760043567ffffffffffffffff81116105bc578036036101206003198201126105bc57611548613e2d565b60c482013590602219018112156105bc5781019060048201359167ffffffffffffffff83116105bc5760248101908360061b80360383136105bc5760046020916115918761387a565b9661159f60405198896135a2565b875282870193010101913683116105bc57905b8282106117be575050508151916115c88361387a565b926115d660405194856135a2565b808452601f196115e58261387a565b015f5b81811061179b57505064ffffffffff4216916001600160801b0361160b82613b57565b51511664ffffffffff80602061162085613b57565b51015116850116604051916116348361354d565b8252602082015261164486613b57565b5261164e85613b57565b5060015b8281106117265750505061166882600401613a05565b9261167560248401613a05565b9261168260448201613933565b916064820135936001600160a01b0385168095036105bc5760209661171e966116de966001600160801b03611713976001600160a01b036116c560848a01613a19565b94816116d360a48c01613a19565b976040519d8e613530565b168c52168c8b0152166040890152606088015215156080870152151560a086015260c085015260e084015260e43691016138c8565b610100820152613e87565b604051908152f35b806001600160801b0361173b60019385613b64565b51511664ffffffffff8060206117545f1986018c613b64565b510151168160206117658689613b64565b510151160116604051916117788361354d565b825260208201526117898289613b64565b526117948188613b64565b5001611652565b6020906040516117aa8161354d565b5f81525f83820152828289010152016115e8565b60206040916117cd3685613892565b8152019101906115b2565b346105bc5760203660031901126105bc5760043560606101606040516117fd81613569565b5f81525f60208201525f60408201525f838201525f60808201525f60a08201525f60c08201525f60e08201525f6101008201525f61012082015260405161184381613586565b5f81525f60208201525f60408201526101408201520152805f52600a60205260ff600160405f20015460a81c161561062f57805f52600a60205260405f2060405191610140830183811067ffffffffffffffff821117611b03576040528154916001600160a01b0383168452602084019264ffffffffff8160a01c168452604085019064ffffffffff8160c81c16825285606081019260ff8360f01c1615158452608082019260f81c1515835260018501549260a08301956001600160a01b0385168752611940600260c086019260ff8860a01c161515845260ff61010060e0890198828b60a81c1615158a52019860b01c1615158852016139d3565b6101208b0190815261195189613c5f565b600581101561121d57600214611afb575b5196516001600160a01b0316925164ffffffffff169551151590511515935115159451151595885f52600360205260405f20546001600160a01b03169a516001600160a01b0316995164ffffffffff16985f52600b60205260405f2092511515926040519a6119d08c613569565b8b5260208b019b8c5260408b01998a5260608b0191825260808b0192835260a08b0193845260c08b0194855260e08b019586526101008b019687526101208b019788526101408b01988952611a249061395f565b986101608b01998a526040519b8c9b60208d52516001600160a01b031660208d0152516001600160a01b031660408c01525164ffffffffff1660608b01525164ffffffffff1660808a015251151560a089015251151560c0880152516001600160a01b031660e08701525115156101008601525115156101208501525115156101408401525180516001600160801b031661016084015260208101516001600160801b0316610180840152604001516001600160801b03166101a0830152516101c082016101c090526101e08201610b89916134d4565b5f8752611962565b634e487b7160e01b5f52604160045260245ffd5b346105bc5760203660031901126105bc5760043567ffffffffffffffff81116105bc57611b489036906004016134a3565b90611b51613e2d565b5f915b808310611b5d57005b611b6883828461390f565b3592611b72613e2d565b835f52600a60205260ff600160405f20015460a81c1615611ebc57835f52600a60205260ff600160405f20015460a01c165f14611bbc57836315efa0f360e11b5f5260045260245ffd5b909192805f52600a60205260405f205460f81c611eaa57611bf1815f52600a6020526001600160a01b0360405f205416331490565b15611e9457611bff81613b78565b90805f52600a602052611c17600260405f20016139d3565b916001600160801b038351166001600160801b0382161015611e8157815f52600a60205260ff60405f205460f01c1615611e6e57806001600160801b03602081611c6b948188511603169501511690613616565b5f828152600a6020526040902080547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b179055916001600160801b038316908115611e49575b825f52600a602052600360405f20016001600160801b0382166001600160801b0319825416179055825f52600a6020526001600160a01b0360405f205416835f5260036020526001600160a01b0360405f20541694845f52600a60205285827f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa50611d7d6001600160a01b03600160405f2001541694611d55888588614809565b604080518b81526001600160801b03808b166020830152909216908201529081906060820190565b0390a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051868152a1845f52600960205260ff60405f205416611dce575b50505050506001019190611b54565b60405193630d4af11f60e31b855260048501526024840152604483015260648201526020816084815f865af19081156104d857630d4af11f60e31b916001600160e01b0319915f91611e2b575b5016036104975780808080611dbf565b611e43915060203d81116104d1576104c381836135a2565b87611e1b565b825f52600a602052600160405f2001600160a01b60ff60a01b19825416179055611cb5565b50635dd950cb60e11b5f5260045260245ffd5b506308aca53f60e21b5f5260045260245ffd5b632082501160e01b5f526004523360245260445ffd5b63d0a172b360e01b5f5260045260245ffd5b8363699d2de960e01b5f5260045260245ffd5b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600b602052610b89611f1460405f2061395f565b6040519182916020835260208301906134d4565b346105bc5760203660031901126105bc57600435611f44613e2d565b805f52600a60205260ff600160405f20015460a81c161561062f57611f6881613c5f565b600581101561121d5760048103611f8c57506315efa0f360e11b5f5260045260245ffd5b60038103611fa7575063d0a172b360e01b5f5260045260245ffd5b60021461206357611fcc815f52600a6020526001600160a01b0360405f205416331490565b15611e9457805f52600a60205260ff60405f205460f01c1615612051576020817ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7925f52600a825260405f2060ff60f01b19815416905560405190807f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f5f80a28152a1005b635dd950cb60e11b5f5260045260245ffd5b6308aca53f60e21b5f5260045260245ffd5b346105bc5760203660031901126105bc576004356001600160a01b0381168091036105bc576001600160a01b035f5416338103612150575060085490806001600160a01b03198316176008556001600160a01b036040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a26007545f19810190811161213c5760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a1005b634e487b7160e01b5f52601160045260245ffd5b6331b339a960e21b5f526004523360245260445ffd5b346105bc5760203660031901126105bc5761217f613429565b5f546001600160a01b03811633810361215057506001600160a01b036001600160a01b0319921691829116175f55337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf805f80a3005b346105bc5760203660031901126105bc576001600160a01b036121f5613429565b168015612212575f526004602052602060405f2054604051908152f35b7f89c62b64000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b346105bc5760203660031901126105bc57602061225c600435613b36565b6001600160a01b0360405191168152f35b346105bc5760203660031901126105bc57600435612289613947565b50805f52600a60205260ff600160405f20015460a81c161561062f575f908152600a6020526040908190205481519064ffffffffff60c882901c81169160a01c166122d38361354d565b825260208201526122f98251809264ffffffffff60208092828151168552015116910152565bf35b346105bc5760403660031901126105bc5760043567ffffffffffffffff81116105bc5761232c9036906004016134a3565b9060243567ffffffffffffffff81116105bc5761234d9036906004016134a3565b919092612358613e2d565b828103612671575f5b81811061236a57005b61237581838561390f565b3561238182848661390f565b355f5260036020526001600160a01b0360405f205416906123ab6123a684888a61390f565b613933565b916123b4613e2d565b815f52600a60205260ff600160405f20015460a81c161561101357815f52600a60205260ff600160405f20015460a01c1661265e57801561099a576001600160801b03831690811561098757825f5260036020526001600160a01b0360405f20541693848214158061264e575b612633576001600160801b0361243685614685565b16808411612619575061245b90845f52600a602052600260405f20015460801c6146ab565b5f848152600a6020526040902060020180546001600160801b031660809290921b6001600160801b031916919091178155612495906139d3565b6001600160801b036124b98160208401511692826040818351169201511690613616565b1611156125e7575b825f52600a6020526001600160a01b03600160405f200154166124e5838383614809565b81847f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d6020604051878152a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051858152a183331415806125d1575b612556575b50505050600101612361565b604051926392b9102b60e01b84526004840152336024840152604483015260648201526020816084815f865af19081156104d8576392b9102b60e01b916001600160e01b0319915f916125b3575b5016036104975780808061254a565b6125cb915060203d81116104d1576104c381836135a2565b896125a4565b50835f52600960205260ff60405f205416612545565b5f838152600a6020526040902060018101805460ff60a01b1916600160a01b179055805460ff60f01b191690556124c1565b838563066920d760e01b5f5260045260245260445260645ffd5b508263350b320360e11b5f526004523360245260445260645ffd5b5061265884614560565b15612421565b506315efa0f360e11b5f5260045260245ffd5b90507fa5ed43e6000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f57610a526020916145d2565b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f61271482613c5f565b600581101561121d57600203612732575b6020906040519015158152f35b505f52600a602052602060ff60405f205460f01c16612725565b346105bc575f3660031901126105bc5760206001600160a01b0360085416604051908152f35b346105bc5760203660031901126105bc5760043561278e613e2d565b805f52600a60205260ff600160405f20015460a81c161561062f57805f52600a60205260ff600160405f20015460a01c161561290b576127cd81614560565b15611e9457805f5260036020526001600160a01b0360405f205416151580612904575b806128e7575b6128d5577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051838152a1805f5260036020526001600160a01b0360405f205416801590811561289e575b825f52600360205260405f206001600160a01b03198154169055825f827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a45061288c57005b637e27328960e01b5f5260045260245ffd5b6128bd835f52600560205260405f206001600160a01b03198154169055565b805f52600460205260405f205f198154019055612844565b634274c8e160e11b5f5260045260245ffd5b50805f52600a60205260ff600160405f20015460b01c16156127f6565b505f6127f0565b7f6121eb36000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346105bc5761118061294736613469565b90604051926129576020856135a2565b5f8452613a26565b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f575f52600a602052602060ff600160405f20015460a01c166040519015158152f35b346105bc5760203660031901126105bc576004356129cb613e2d565b805f52600a60205260ff600160405f20015460a81c161561062f57805f52600a60205260ff600160405f20015460a01c165f14612a14576315efa0f360e11b5f5260045260245ffd5b805f52600a60205260405f205460f81c611eaa57612a46815f52600a6020526001600160a01b0360405f205416331490565b15611e9457612a5481613b78565b90805f52600a602052612a6c600260405f20016139d3565b916001600160801b038351166001600160801b0382161015611e8157815f52600a60205260ff60405f205460f01c1615611e6e57806001600160801b03602081612ac0948188511603169501511690613616565b5f828152600a6020526040902080547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b179055916001600160801b038316908115612c61575b825f52600a602052600360405f20016001600160801b0382166001600160801b0319825416179055825f52600a6020526001600160a01b0360405f205416835f5260036020526001600160a01b0360405f20541694845f52600a60205285827f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa50612baa6001600160a01b03600160405f2001541694611d55888588614809565b0390a47ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051868152a1845f52600960205260ff60405f205416612bed57005b60405193630d4af11f60e31b855260048501526024840152604483015260648201526020816084815f865af19081156104d857630d4af11f60e31b916001600160e01b0319915f91612c425750160361049757005b612c5b915060203d6020116104d1576104c381836135a2565b8461048e565b825f52600a602052600160405f2001600160a01b60ff60a01b19825416179055612b0a565b346105bc5760203660031901126105bc57612c9f613429565b6001600160a01b035f541690338203612dde57806001600160a01b03913b15612db257166040516301ffc9a760e01b81527ff8ee98d3000000000000000000000000000000000000000000000000000000006004820152602081602481855afa9081156104d8575f91612d83575b5015612d5857805f52600960205260405f20600160ff198254161790556040519081527fb4378d4e289cb3f40f4f75a99c9cafa76e3df1c4dc31309babc23dc91bd7280160203392a2005b7ff1dc125d000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b612da5915060203d602011612dab575b612d9d81836135a2565b8101906138f7565b82612d0d565b503d612d93565b7f295097c8000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b506331b339a960e21b5f526004523360245260445ffd5b346105bc5760203660031901126105bc5760043567ffffffffffffffff81116105bc5761014060031982360301126105bc57612e2f613e2d565b604051612e3b81613530565b612e4782600401613455565b8152612e5560248301613455565b6020820152612e66604483016135e0565b604082015260648201356001600160a01b03811681036105bc576060820152612e9160848301613523565b6080820152612ea260a48301613523565b60a0820152612eb360c48301613868565b60c082015260e482013567ffffffffffffffff81116105bc57820191366023840112156105bc57600483013592612ee98461387a565b90612ef760405192836135a2565b848252602060048184019660061b83010101903682116105bc57602401945b818610612f3857602061171e86611713878760e08401526101043691016138c8565b6020604091612f473689613892565b815201950194612f16565b346105bc5760203660031901126105bc576001600160a01b03612f73613429565b165f526009602052602060ff60405f2054166040519015158152f35b346105bc575f3660031901126105bc5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346105bc57611180612fda36613469565b91613636565b346105bc575f3660031901126105bc576020600754604051908152f35b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f5761303590613c5f565b600581101561121d578060209115908115613056575b506040519015158152f35b60019150148261304b565b346105bc5760203660031901126105bc57600435805f52600a60205260ff600160405f20015460a81c161561062f576020905f90805f52600a835260ff60405f205460f01c16806130f6575b6130c4575b506001600160801b0360405191168152f35b6130f09150805f52600a83526130ea6001600160801b03600260405f2001541691613b78565b90613616565b826130b2565b50805f52600a835260ff600160405f20015460a01c16156130ad565b346105bc5760403660031901126105bc5761312b613429565b60243561313781613b36565b33151580613204575b806131d1575b6131a55781906001600160a01b0380851691167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a45f5260056020526001600160a01b0360405f2091166001600160a01b03198254161790555f80f35b7fa9fbf51f000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b506001600160a01b0381165f52600660205260405f206001600160a01b0333165f5260205260ff60405f20541615613146565b50336001600160a01b0382161415613140565b346105bc5760203660031901126105bc57602061225c6004356135f4565b346105bc575f3660031901126105bc576040515f6001548060011c906001811680156132e6575b602083108114611420578285529081156113fc575060011461328857610b898361138a818503826135a2565b91905060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6915f905b8082106132cc5750909150810160200161138a61137a565b9192600181602092548385880101520191019092916132b4565b91607f169161325c565b346105bc575f3660031901126105bc57602060405167016345785d8a00008152f35b346105bc5760203660031901126105bc57600435906001600160e01b031982168092036105bc57817f49064906000000000000000000000000000000000000000000000000000000006020931490811561336e575b5015158152f35b7f80ac58cd000000000000000000000000000000000000000000000000000000008114915081156133b9575b81156133a8575b5083613367565b6301ffc9a760e01b915014836133a1565b7f5b5e139f000000000000000000000000000000000000000000000000000000008114915061339a565b5f5b8381106133f45750505f910152565b81810151838201526020016133e5565b9060209161341d815180928185528580860191016133e3565b601f01601f1916010190565b600435906001600160a01b03821682036105bc57565b602435906001600160a01b03821682036105bc57565b35906001600160a01b03821682036105bc57565b60609060031901126105bc576004356001600160a01b03811681036105bc57906024356001600160a01b03811681036105bc579060443590565b9181601f840112156105bc5782359167ffffffffffffffff83116105bc576020808501948460051b0101116105bc57565b90602080835192838152019201905f5b8181106134f15750505090565b825180516001600160801b0316855260209081015164ffffffffff1681860152604090940193909201916001016134e4565b359081151582036105bc57565b610120810190811067ffffffffffffffff821117611b0357604052565b6040810190811067ffffffffffffffff821117611b0357604052565b610180810190811067ffffffffffffffff821117611b0357604052565b6060810190811067ffffffffffffffff821117611b0357604052565b90601f8019910116810190811067ffffffffffffffff821117611b0357604052565b67ffffffffffffffff8111611b0357601f01601f191660200190565b35906001600160801b03821682036105bc57565b6135fd81613b36565b505f5260056020526001600160a01b0360405f20541690565b906001600160801b03809116911603906001600160801b03821161213c57565b91906001600160a01b03168015610cf157815f5260036020526001600160a01b0360405f205416151580613860575b80613843575b613830577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051848152a1815f5260036020526001600160a01b0360405f2054169282331515928361377b575b6001600160a01b03935085613744575b805f52600460205260405f2060018154019055815f52600360205260405f20816001600160a01b0319825416179055857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a41680830361372c57505050565b6364283d7b60e01b5f5260045260245260445260645ffd5b613763825f52600560205260405f206001600160a01b03198154169055565b855f52600460205260405f205f1981540190556136cb565b91929050806137d9575b15613792578282916136bb565b82846137aa57637e27328960e01b5f5260045260245ffd5b7f177e802f000000000000000000000000000000000000000000000000000000005f523360045260245260445ffd5b503384148015613807575b806137855750825f526005602052336001600160a01b0360405f20541614613785565b50835f52600660205260405f206001600160a01b0333165f5260205260ff60405f2054166137e4565b50634274c8e160e11b5f5260045260245ffd5b50815f52600a60205260ff600160405f20015460b01c161561366b565b506001613665565b359064ffffffffff821682036105bc57565b67ffffffffffffffff8111611b035760051b60200190565b91908260409103126105bc576040516138aa8161354d565b60206138c38183956138bb816135e0565b855201613868565b910152565b91908260409103126105bc576040516138e08161354d565b60208082946138ee81613455565b84520135910152565b908160209103126105bc575180151581036105bc5790565b919081101561391f5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160801b03811681036105bc5790565b604051906139548261354d565b5f6020838281520152565b90815461396b8161387a565b9261397960405194856135a2565b81845260208401905f5260205f205f915b8383106139975750505050565b6001602081926040516139a98161354d565b64ffffffffff86546001600160801b038116835260801c168382015281520192019201919061398a565b906040516139e081613586565b60406001600160801b03600183958054838116865260801c6020860152015416910152565b356001600160a01b03811681036105bc5790565b3580151581036105bc5790565b90613a32838284613636565b803b613a3f575b50505050565b602091613a856001600160a01b03809316956040519586948594630a85bd0160e11b86523360048701521660248501526044840152608060648401526084830190613404565b03815f865af15f9181613af5575b50613ac15750613aa1614656565b80519081613abc5782633250574960e11b5f5260045260245ffd5b602001fd5b6001600160e01b0319630a85bd0160e11b911603613ae357505f808080613a39565b633250574960e11b5f5260045260245ffd5b613b0f91925060203d6020116104d1576104c381836135a2565b905f613a93565b908160209103126105bc57516001600160e01b0319811681036105bc5790565b805f5260036020526001600160a01b0360405f20541690811561288c575090565b80511561391f5760200190565b805182101561391f5760209160051b010190565b9064ffffffffff421691805f52600b602052613b9660405f2061395f565b908364ffffffffff6020613ba985613b57565b5101511611613c5857805f52600a6020528364ffffffffff60405f205460c81c161115613c3957506001600160801b03613be282613b57565b515116916001925b8251841015613c32578464ffffffffff6020613c068787613b64565b5101511611613c32576001600160801b0360019181613c258787613b64565b5151160116930192613bea565b9350915050565b919250505f52600a6020526001600160801b03600260405f2001541690565b505f925050565b805f52600a60205260ff600160405f20015460a01c165f14613c815750600490565b805f52600a60205260405f205460f81c613ced57805f52600a60205264ffffffffff60405f205460a01c164210613ce857613cbb81613b78565b905f52600a6020526001600160801b0380600260405f200154169116105f14613ce357600190565b600290565b505f90565b50600390565b90805f5260036020526001600160a01b0360405f205416151580613e1b575b80613dfe575b6128d5577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce76020604051838152a1805f5260036020526001600160a01b038060405f2054169283613dc7575b1680613daf575b815f52600360205260405f20816001600160a01b0319825416179055827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a490565b805f52600460205260405f2060018154019055613d6b565b613de6835f52600560205260405f206001600160a01b03198154169055565b835f52600460205260405f205f198154019055613d64565b50805f52600a60205260ff600160405f20015460b01c1615613d18565b506001600160a01b0382161515613d12565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003613e5f57565b7fa1c0d6e5000000000000000000000000000000000000000000000000000000005f5260045ffd5b90613ea96001600160801b0360408401511660206101008501510151906146cb565b916001600160801b038351169060e08101519160c082019264ffffffffff845116821561453857801561451057815180156144e8577f000000000000000000000000000000000000000000000000000000000000000081116144bd575064ffffffffff6020613f1784613b57565b5101511681101561447957505f905f905f81515f905b8082106143f1575050505064ffffffffff804216911690818110156143c35750506001600160801b03169081810361439557505060075493845f52600a60205260405f20916001600160801b038251166001600160801b036002850191166001600160801b03198254161790556001600160a01b03606082015116916001600160a01b036001850193166001600160a01b031984541617835560808201948551151560ff60f01b197eff00000000000000000000000000000000000000000000000000000000000087549260f01b169116178555835493750100000000000000000000000000000000000000000060a08501957fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff76ff000000000000000000000000000000000000000000008851151560b01b169116171790556001600160a01b0380845116166001600160a01b03198654161785555184549060e0840151917fffff00000000000000000000ffffffffffffffffffffffffffffffffffffffff78ffffffffff00000000000000000000000000000000000000007dffffffffff0000000000000000000000000000000000000000000000000060206140f98751975f19890190613b64565b51015160c81b169360a01b169116171785555f5b8181106142e3575050600187016007556001600160a01b036020830151168015610cf157614143886001600160a01b0392613cf3565b166142b75786826141916001600160a01b0360607ffeb1cb9ce021c8bd5fb1eb836e6284c68866fa32d1d844238de19955238f8076960151166001600160801b0385511690309033906147a8565b6001600160801b0360208401511680614287575b506001600160a01b038151169461427c61425e6001600160a01b03602085015116986001600160a01b036060860151169a511515935115156001600160a01b0361010060e088015193549764ffffffffff604051996142038b61354d565b818160a01c168b5260c81c1660208a015201515116946001600160801b0360206040519a8b9a8b5233828c01528281511660408c01520151166060890152608088015260a087015261014060c08701526101408601906134d4565b9260e085019064ffffffffff60208092828151168552015116910152565b6101208301520390a4565b6142b1906001600160a01b036060840151166001600160a01b0361010085015151169033906147a8565b5f6141a5565b7f73c6ac6e000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b885f52600b60205260405f20906142fe8160e0870151613b64565b5182549268010000000000000000841015611b03576001840180825584101561391f576001936020915f52815f2001916001600160801b0380825116166001600160801b031984541617835501517fffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffffff74ffffffffff0000000000000000000000000000000083549260801b1691161790550161410d565b7fa4cdf853000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b7f879842de000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b9193509193614415906001600160801b0361440c8588613b64565b515116906146ab565b9364ffffffffff8060206144298685613b64565b5101511694168085111561444557506001849301909291613f2d565b8490847fbfc5f2fa000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b64ffffffffff602061448a84613b57565b51015116907fab900963000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b7f76d9c284000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7f814426ed000000000000000000000000000000000000000000000000000000005f5260045ffd5b7feaa6c316000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f779f8816000000000000000000000000000000000000000000000000000000005f5260045ffd5b805f5260036020526001600160a01b0360405f205416908133149182156145a6575b50811561458d575090565b90506001600160a01b036145a133926135f4565b161490565b9091505f52600660205260405f206001600160a01b0333165f5260205260ff60405f205416905f614582565b805f52600a6020526145e9600260405f20016139d3565b90805f52600a60205260ff600160405f20015460a01c165f146146175750602001516001600160801b031690565b90815f52600a60205260405f205460f81c614639575061463690613b78565b90565b61463691506001600160801b036040818351169201511690613616565b3d15614680573d90614667826135c4565b9161467560405193846135a2565b82523d5f602084013e565b606090565b61463690614692816145d2565b905f52600a602052600260405f20015460801c90613616565b906001600160801b03809116911601906001600160801b03821161213c57565b9190916040516146da8161354d565b5f81525f6020820152926001600160801b03821690811561478b5767016345785d8a00008111614754576147166001600160801b0391836148de565b1660208501918183521115614740576001600160801b03918261473b92511690613616565b168252565b634e487b7160e01b5f52600160045260245ffd5b7ffc8a7df4000000000000000000000000000000000000000000000000000000005f5260045267016345785d8a000060245260445ffd5b505050905060405161479c8161354d565b5f81525f602082015290565b9091926001600160a01b036148079481604051957f23b872dd0000000000000000000000000000000000000000000000000000000060208801521660248601521660448401526064830152606482526148026084836135a2565b614859565b565b614807926001600160a01b03604051937fa9059cbb0000000000000000000000000000000000000000000000000000000060208601521660248401526044830152604482526148026064836135a2565b5f806001600160a01b0361488293169360208151910182865af161487b614656565b908361498c565b80519081151591826148c3575b50506148985750565b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b6148d692506020809183010191016138f7565b155f8061488f565b9091905f198382098382029182808310920391808303921461497b57670de0b6b3a764000082101561494b577faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106699394670de0b6b3a7640000910990828211900360ee1b910360121c170290565b84907f5173648d000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b5050670de0b6b3a764000090049150565b906149c957508051156149a157805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b81511580614a0f575b6149da575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b156149d256fea164736f6c634300081a000a"; - bytes public constant BYTECODE_MERKLE_LOCKUP_FACTORY = + bytes public constant BYTECODE_MERKLE_FACTORY = hex"60808060405234601557613bb9908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c80631e3238761461044c5780634d7c0f11146103795763769bed201461003a575f80fd5b346103755760c03660031901126103755760043567ffffffffffffffff81116103755761006b9036906004016108c2565b602435906001600160a01b03821691828103610375576040366043190112610375576040519061009a8261080f565b60443564ffffffffff8116810361037557825260643564ffffffffff811681036103755760208301528251906020840151151583604086015192606087015160808801519160405180602081019460208652604082016100f9916109ca565b03601f198101825261010b908261082b565b60a08a01519360c08b0151604051818192519081602084019160200191610131926109a9565b810103808252610144906020018261082b565b61014d906109ef565b9060e08c01511515926040519560208701988961017c9164ffffffffff60208092828151168552015116910152565b6040875261018b60608861082b565b6040519a8b9a60208c019d8e3360601b90526bffffffffffffffffffffffff199060601b1660348d015260f81b60488c015260d81b7fffffffffff0000000000000000000000000000000000000000000000000000001660498b01526bffffffffffffffffffffffff199060601b16604e8a015251908160628a0161020f926109a9565b8701946062860152608285015260f81b60a28401526bffffffffffffffffffffffff199060601b1660a383015251918260b7830161024c926109a9565b0160620103605501601f1981018252610265908261082b565b51902060405161157280820182811067ffffffffffffffff821117610361578291610ae88339608081526102c260406102a16080840189610a61565b92896020820152018664ffffffffff60208092828151168552015116910152565b03905ff59283156103565761031961033b937f2ba0fe49588281dbb122dd3b7f3e2b3396338f70dbe3c62bf3e3888b4ba7ffb8926001600160a01b036020971695869560405194859460c0865260c0860190610a61565b9289850152604084019064ffffffffff60208092828151168552015116910152565b608435608083015260a43560a08301520390a2604051908152f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b5f80fd5b346103755760203660031901126103755760043567ffffffffffffffff811161037557366023820112156103755780600401359067ffffffffffffffff8211610375573660248360061b83010111610375575f90815b8383101561042d5760248360061b830101359067ffffffffffffffff82168092036103755767ffffffffffffffff160167ffffffffffffffff8111610419576001909201916103cf565b634e487b7160e01b5f52601160045260245ffd5b602090670de0b6b3a764000067ffffffffffffffff6040519216148152f35b346103755760a03660031901126103755760043567ffffffffffffffff81116103755761047d9036906004016108c2565b6024356001600160a01b03811690818103610375576044359067ffffffffffffffff8211610375573660238301121561037557816004013567ffffffffffffffff811161036157604051926104d860208360051b018561082b565b8184526024602085019260061b8201019036821161037557602401915b8183106107c2575050505f9082515f905b8082106107835750508451906020860151151584604088015192606089015160808a0151916040518060208101946020865260408201610545916109ca565b03601f1981018252610557908261082b565b8b60a08101519460c082015160405181819251908160208401916020019161057e926109a9565b810103808252610591906020018261082b565b61059a906109ef565b9160e001511515926040519586602081019960208b52604082016105bd91610a11565b03601f19810188526105cf908861082b565b6040519a8b9a60208c019d8e3360601b90526bffffffffffffffffffffffff199060601b1660348d015260f81b60488c015260d81b7fffffffffff0000000000000000000000000000000000000000000000000000001660498b01526bffffffffffffffffffffffff199060601b16604e8a015251908160628a01610653926109a9565b8701946062860152608285015260f81b60a28401526bffffffffffffffffffffffff199060601b1660a383015251918260b78301610690926109a9565b0160620103605501601f19810182526106a9908261082b565b519020604051611b538082019082821067ffffffffffffffff8311176103615782916106fa9161205a8439606081526106e5606082018a610a61565b90886020820152604081830391015286610a11565b03905ff58015610356576020947ffe44018cf74992b2720702385a1728bd329dd136e4f651203176c81c12710a8b926107626001600160a01b03610750941696879660405195869560c0875260c0870190610a61565b918a8601528482036040860152610a11565b906060830152606435608083015260843560a08301520390a2604051908152f35b909284518410156107ae5760019064ffffffffff6020808760051b8901015101511601930190610506565b634e487b7160e01b5f52603260045260245ffd5b60408336031261037557604051906107d98261080f565b83359067ffffffffffffffff8216820361037557826020926040945261080083870161085a565b838201528152019201916104f5565b6040810190811067ffffffffffffffff82111761036157604052565b90601f8019910116810190811067ffffffffffffffff82111761036157604052565b3590811515820361037557565b359064ffffffffff8216820361037557565b81601f820112156103755780359067ffffffffffffffff821161036157604051926108a1601f8401601f19166020018561082b565b8284526020838301011161037557815f926020809301838601378301015290565b919091610100818403126103755760405190610100820182811067ffffffffffffffff82111761036157604052819381356001600160a01b03811681036103755783526109116020830161084d565b60208401526109226040830161085a565b604084015260608201356001600160a01b0381168103610375576060840152608082013567ffffffffffffffff8111610375578161096191840161086c565b608084015260a082013560a084015260c08201359067ffffffffffffffff8211610375578261099960e094926109a49486940161086c565b60c08601520161084d565b910152565b5f5b8381106109ba5750505f910152565b81810151838201526020016109ab565b906020916109e3815180928185528580860191016109a9565b601f01601f1916010190565b602081519101519060208110610a03575090565b5f199060200360031b1b1690565b90602080835192838152019201905f5b818110610a2e5750505090565b8251805167ffffffffffffffff16855260209081015164ffffffffff168186015260409094019390920191600101610a21565b906001600160a01b03825116815260208201511515602082015264ffffffffff60408301511660408201526001600160a01b03606083015116606082015260e080610adc610ac0608086015161010060808701526101008601906109ca565b60a086015160a086015260c086015185820360c08701526109ca565b93015115159101529056fe610160806040523461042857611572803803809161001d8285610560565b833981019080820390608082126104285780516001600160401b03811161042857810190610100828503126104285760405161010081016001600160401b038111828210176105355760405282516001600160a01b038116810361042857815261008960208401610583565b6020820190815261009c60408501610590565b60408301908152606085015194906001600160a01b0386168603610428576060840195865260808201516001600160401b03811161042857886100e09184016105de565b6080850190815260a08381015190860190815260c084015190999192916001600160401b0382116104285761011c60e09161012a9387016105de565b9460c0880195865201610583565b9360e0860194855260208701519560018060a01b038716998a880361042857604090603f1901126104285760408051989089016001600160401b0381118a8210176105355761018d9160609160405261018560408201610590565b8b5201610590565b9860208901998a52855151602081116105495750515f80546001600160a01b0319166001600160a01b0392831617905590511660805251151560a0525164ffffffffff1660c0525180519097906001600160401b03811161053557600154600181811c9116801561052b575b602082101461051757601f81116104b4575b506020601f821160011461044857819064ffffffffff98999a5f9261043d575b50508160011b915f199060031b1c1916176001555b5160e052516040516102736020828161026281830196878151938492016105bd565b81010301601f198101835282610560565b519051906020811061042c575b50610100525115156101205261014052511669ffffffffff0000000000600454925160281b169160018060501b031916171760045560018060a01b0360805116604051905f806020840163095ea7b360e01b815285602486015281196044860152604485526102f0606486610560565b84519082855af16102ff610623565b816103f1575b50806103e7575b156103a2575b604051610e4e90816107248239608051818181610409015281816106440152610ae6015260a05181818161067501526109fe015260c0518181816101520152818161095501528181610c250152610d80015260e05181818161029f015261059d01526101005181610caa01526101205181818161069f01526109c201526101405181818161019501526107b40152f35b6103da6103df936040519063095ea7b360e01b602083015260248201525f6044820152604481526103d4606482610560565b82610652565b610652565b5f8080610312565b50803b151561030c565b8051801592508215610406575b50505f610305565b81925090602091810103126104285760206104219101610583565b5f806103fe565b5f80fd5b5f199060200360031b1b165f610280565b015190505f8061022b565b601f1982169960015f52815f209a5f5b81811061049c57509164ffffffffff999a9b91846001959410610484575b505050811b01600155610240565b01515f1960f88460031b161c191690555f8080610476565b838301518d556001909c019b60209384019301610458565b60015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f830160051c8101916020841061050d575b601f0160051c01905b818110610502575061020b565b5f81556001016104f5565b90915081906104ec565b634e487b7160e01b5f52602260045260245ffd5b90607f16906101f9565b634e487b7160e01b5f52604160045260245ffd5b630f39860960e01b5f52600452602060245260445ffd5b601f909101601f19168101906001600160401b0382119082101761053557604052565b5190811515820361042857565b519064ffffffffff8216820361042857565b6001600160401b03811161053557601f01601f191660200190565b5f5b8381106105ce5750505f910152565b81810151838201526020016105bf565b81601f820112156104285780516105f4816105a2565b926106026040519485610560565b818452602082840101116104285761062091602080850191016105bd565b90565b3d1561064d573d90610634826105a2565b916106426040519384610560565b82523d5f602084013e565b606090565b5f8061067a9260018060a01b03169360208151910182865af1610673610623565b90836106c5565b80519081151591826106a2575b50506106905750565b635274afe760e01b5f5260045260245ffd5b81925090602091810103126104285760206106bd9101610583565b155f80610687565b906106e957508051156106da57805190602001fd5b630a12f52160e11b5f5260045ffd5b8151158061071a575b6106fa575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b156106f256fe6080806040526004361015610012575f80fd5b5f3560e01c90816306fdde0314610c94575080631686c90914610a2357806316c3549d146109e75780631bfd6814146109ab5780633bfe03a81461097d5780633f31ae3f1461042d5780634800d97f146103ea57806349fc73dd146102e65780634e390d3e146102c257806351e75e8b1461028857806375829def146101d357806390e64d13146101b95780639e93e57714610176578063bb4b573414610135578063ce516507146100f55763f851a440146100cc575f80fd5b346100f1575f3660031901126100f15760206001600160a01b035f5416604051908152f35b5f80fd5b346100f15760203660031901126100f157602061012b60043560ff6001918060081c5f526002602052161b60405f205416151590565b6040519015158152f35b346100f1575f3660031901126100f157602060405164ffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100f1575f3660031901126100f15760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100f1575f3660031901126100f157602061012b610d78565b346100f15760203660031901126100f1576101ec610d24565b5f546001600160a01b03811633810361025957506001600160a01b037fffffffffffffffffffffffff0000000000000000000000000000000000000000921691829116175f55337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf805f80a3005b7fc6cce6a4000000000000000000000000000000000000000000000000000000005f526004523360245260445ffd5b346100f1575f3660031901126100f15760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346100f1575f3660031901126100f157602064ffffffffff60035416604051908152f35b346100f1575f3660031901126100f1576040515f6001548060011c906001811680156103e0575b6020831081146103cc578285529081156103a8575060011461034a575b6103468361033a81850382610d56565b60405191829182610cdd565b0390f35b91905060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6915f905b80821061038e5750909150810160200161033a61032a565b919260018160209254838588010152019101909291610376565b60ff191660208086019190915291151560051b8401909101915061033a905061032a565b634e487b7160e01b5f52602260045260245ffd5b91607f169161030d565b346100f1575f3660031901126100f15760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100f15760803660031901126100f1576004356024356001600160a01b0381168091036100f157604435916fffffffffffffffffffffffffffffffff83168093036100f1576064359067ffffffffffffffff82116100f157366023830112156100f157816004013567ffffffffffffffff81116100f1578060051b92602484820101903682116100f1576040516020810190858252876040820152886060820152606081526104de608082610d56565b51902060405160208101918252602081526104fa604082610d56565b51902092610506610d78565b6109265761052b8560ff6001918060081c5f526002602052161b60405f205416151590565b6108fa5761053f6020604051970187610d56565b8552602401602085015b8282106108ea57505050935f945b83518610156105995760208660051b85010151908181105f14610588575f52602052600160405f205b950194610557565b905f52602052600160405f20610580565b84907f0000000000000000000000000000000000000000000000000000000000000000036108c25760035464ffffffffff8116156108a8575b508260081c5f52600260205260405f20600160ff85161b81541790556001600160a01b035f54169160405161060681610d3a565b5f81525f602082015260405193610100850185811067ffffffffffffffff8211176108945760405284526020840183815260408501838152606086017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815260808701907f00000000000000000000000000000000000000000000000000000000000000001515825260a08801927f000000000000000000000000000000000000000000000000000000000000000015158452604051946106cf86610d3a565b60045464ffffffffff8116875260281c64ffffffffff16602087015260c08a0195865260e08a01968752604051997fab167ccc000000000000000000000000000000000000000000000000000000008b52516001600160a01b031660048b0152516001600160a01b031660248a0152516fffffffffffffffffffffffffffffffff166044890152516001600160a01b03166064880152511515608487015251151560a486015251805164ffffffffff1660c48601526020015164ffffffffff1660e48501525180516001600160a01b03166101048501526020015161012484015282807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165a925f61014492602095f1928315610889575f93610831575b50907f28b58397e03322f670d6b223cc863f8c148e368b8b615412e6798a641a22842d60406020958594825191825287820152a3604051908152f35b939250906020843d602011610881575b8161084e60209383610d56565b810103126100f15792519192907f28b58397e03322f670d6b223cc863f8c148e368b8b615412e6798a641a22842d6107f5565b3d9150610841565b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b64ffffffffff19164264ffffffffff1617600355836105d2565b7ffe365d76000000000000000000000000000000000000000000000000000000005f5260045ffd5b8135815260209182019101610549565b847fcd4c86cc000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7f99657b41000000000000000000000000000000000000000000000000000000005f524260045264ffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660245260445ffd5b346100f1575f3660031901126100f157604060045464ffffffffff825191818116835260281c166020820152f35b346100f1575f3660031901126100f15760206040517f000000000000000000000000000000000000000000000000000000000000000015158152f35b346100f1575f3660031901126100f15760206040517f000000000000000000000000000000000000000000000000000000000000000015158152f35b346100f15760403660031901126100f157610a3c610d24565b6024356fffffffffffffffffffffffffffffffff81168091036100f1576001600160a01b035f5416338103610259575064ffffffffff6003541680151580610c5f575b80610c50575b610bf657506040515f806001600160a01b0360208401957fa9059cbb000000000000000000000000000000000000000000000000000000008752169485602485015284604485015260448452610adc606485610d56565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001693519082855af13d15610bea573d67ffffffffffffffff811161089457610b4f9160405191610b3f6020601f19601f8401160184610d56565b82523d5f602084013e5b83610db5565b8051908115159182610bc6575b5050610b9b57507f2e9d425ba8b27655048400b366d7b6a1f7180ebdb088e06bb7389704860ffe1f60206001600160a01b035f541692604051908152a3005b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b81925090602091810103126100f157602001518015908115036100f1578480610b5c565b610b4f90606090610b49565b7f6df0cfdb000000000000000000000000000000000000000000000000000000005f524260045264ffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660245260445260645ffd5b50610c59610d78565b15610a85565b5062093a80810164ffffffffff8111610c805764ffffffffff164211610a7f565b634e487b7160e01b5f52601160045260245ffd5b346100f1575f3660031901126100f157610346907f000000000000000000000000000000000000000000000000000000000000000060208201526020815261033a604082610d56565b9190916020815282518060208301525f5b818110610d0e575060409293505f838284010152601f8019910116010190565b8060208092870101516040828601015201610cee565b600435906001600160a01b03821682036100f157565b6040810190811067ffffffffffffffff82111761089457604052565b90601f8019910116810190811067ffffffffffffffff82111761089457604052565b64ffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168015159081610dad575090565b905042101590565b90610df25750805115610dca57805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b81511580610e38575b610e03575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b15610dfb56fea164736f6c634300081a000a610180806040523461044857611b53803803809161001d82856106ab565b83398101906060818303126104485780516001600160401b03811161044857810161010081840312610448576040519061010082016001600160401b038111838210176105025760405280516001600160a01b0381168103610448578252610087602082016106ce565b916020810192835261009b604083016106db565b60408201908152606083015193906001600160a01b0385168503610448576060830194855260808401516001600160401b03811161044857876100df918601610729565b916080840192835260a08501519360a0810194855260c086015160018060401b0381116104485760e06101178b610125938a01610729565b9760c08401988952016106ce565b60e082019081526020890151989097906001600160a01b038a168a03610448576040810151906001600160401b03821161044857018a601f82011215610448578051906001600160401b0382116105025760209b8c6040519d8e61018e828760051b01826106ab565b858152019360061b8301019181831161044857602001925b82841061064f5750505050865151602081116106385750515f80546001600160a01b0319166001600160a01b0392831617905590511660805251151560a0525164ffffffffff1660c052518051906001600160401b0382116105025760015490600182811c9216801561062e575b602083101461061a5781601f8493116105ac575b50602090601f8311600114610546575f9261053b575b50508160011b915f199060031b1c1916176001555b5160e05251604051610286602082816102758183019687815193849201610708565b81010301601f1981018352826106ab565b519051906020811061052a575b506101005251151561012052610140528051905f915f915b81831061044c57836101605260018060a01b036080511660018060a01b03610140511690604051905f806020840163095ea7b360e01b815285602486015281196044860152604485526102ff6064866106ab565b84519082855af161030e610782565b81610411575b5080610407575b156103c2575b6040516112d0908161088382396080518181816105590152818161088e0152610e8e015260a0518181816108b80152610daf015260c0518181816102a101528181610d0901528181610fcd0152611114015260e0518181816103ef01526107260152610100518161103e0152610120518181816108ea0152610d7301526101405181818161011f01526109d00152610160518181816102e5015261060a0152f35b6103fa6103ff936040519063095ea7b360e01b602083015260248201525f6044820152604481526103f46064826106ab565b826107b1565b6107b1565b808080610321565b50803b151561031b565b8051801592508215610426575b505084610314565b819250906020918101031261044857602061044191016106ce565b848061041e565b5f80fd5b91929091906001600160401b03610463858461076e565b5151166001600160401b03918216019081116105165792610484818361076e565b519060045491680100000000000000008310156105025760018301806004558310156104ee5760019260045f5260205f200190838060401b038151166cffffffffff00000000000000006020845493015160401b1691858060681b031916171790550191906102ab565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f199060200360031b1b165f610293565b015190505f8061023e565b60015f9081528281209350601f198516905b818110610594575090846001959493921061057c575b505050811b01600155610253565b01515f1960f88460031b161c191690555f808061056e565b92936020600181928786015181550195019301610558565b60015f529091507fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f840160051c81019160208510610610575b90601f859493920160051c01905b8181106106025750610228565b5f81558493506001016105f5565b90915081906105e7565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610214565b630f39860960e01b5f52600452602060245260445ffd5b6040848303126104485760408051919082016001600160401b03811183821017610502576040528451906001600160401b038216820361044857826020926040945261069c8388016106db565b838201528152019301926101a6565b601f909101601f19168101906001600160401b0382119082101761050257604052565b5190811515820361044857565b519064ffffffffff8216820361044857565b6001600160401b03811161050257601f01601f191660200190565b5f5b8381106107195750505f910152565b818101518382015260200161070a565b81601f8201121561044857805161073f816106ed565b9261074d60405194856106ab565b818452602082840101116104485761076b9160208085019101610708565b90565b80518210156104ee5760209160051b010190565b3d156107ac573d90610793826106ed565b916107a160405193846106ab565b82523d5f602084013e565b606090565b5f806107d99260018060a01b03169360208151910182865af16107d2610782565b9083610824565b8051908115159182610801575b50506107ef5750565b635274afe760e01b5f5260045260245ffd5b819250906020918101031261044857602061081c91016106ce565b155f806107e6565b90610848575080511561083957805190602001fd5b630a12f52160e11b5f5260045ffd5b81511580610879575b610859575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b1561085156fe6080806040526004361015610012575f80fd5b5f3560e01c90816306fdde0314611028575080631686c90914610dd457806316c3549d14610d985780631bfd681414610d5c5780633f31ae3f1461057d5780634800d97f1461053a57806349fc73dd146104365780634e390d3e1461041257806351e75e8b146103d857806375829def1461032357806390e64d1314610309578063936c63d9146102c5578063bb4b573414610284578063bf4ed03f14610183578063ce51650714610143578063da792468146101005763f851a440146100d7575f80fd5b346100fc575f3660031901126100fc5760206001600160a01b035f5416604051908152f35b5f80fd5b346100fc575f3660031901126100fc5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100fc5760203660031901126100fc57602061017960043560ff6001918060081c5f526002602052161b60405f205416151590565b6040519015158152f35b346100fc575f3660031901126100fc5760045461019f81611149565b906101ad60405192836110ea565b80825260045f9081526020830191907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b835b838310610247578486604051918291602083019060208452518091526040830191905f5b818110610211575050500390f35b8251805167ffffffffffffffff16855260209081015164ffffffffff168186015286955060409094019390920191600101610203565b600160208192604051610259816110ce565b64ffffffffff865467ffffffffffffffff8116835260401c16838201528152019201920191906101df565b346100fc575f3660031901126100fc57602060405164ffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100fc575f3660031901126100fc57602060405167ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100fc575f3660031901126100fc57602061017961110c565b346100fc5760203660031901126100fc5761033c6110b8565b5f546001600160a01b0381163381036103a957506001600160a01b037fffffffffffffffffffffffff0000000000000000000000000000000000000000921691829116175f55337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf805f80a3005b7fc6cce6a4000000000000000000000000000000000000000000000000000000005f526004523360245260445ffd5b346100fc575f3660031901126100fc5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346100fc575f3660031901126100fc57602064ffffffffff60035416604051908152f35b346100fc575f3660031901126100fc576040515f6001548060011c90600181168015610530575b60208310811461051c578285529081156104f8575060011461049a575b6104968361048a818503826110ea565b60405191829182611071565b0390f35b91905060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6915f905b8082106104de5750909150810160200161048a61047a565b9192600181602092548385880101520191019092916104c6565b60ff191660208086019190915291151560051b8401909101915061048a905061047a565b634e487b7160e01b5f52602260045260245ffd5b91607f169161045d565b346100fc575f3660031901126100fc5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100fc5760803660031901126100fc57600435602435906001600160a01b0382168092036100fc57604435916001600160801b038316918284036100fc576064359367ffffffffffffffff85116100fc57366023860112156100fc5784600401359467ffffffffffffffff86116100fc5760248660051b8201013681116100fc5767ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016670de0b6b3a76400008103610d3157506040516020810190858252866040820152876060820152606081526106606080826110ea565b519020604051602081019182526020815261067c6040826110ea565b5190209161068861110c565b610cda576106ad8560ff6001918060081c5f526002602052161b60405f205416151590565b610cae576106ba88611149565b976106c8604051998a6110ea565b8852602401602088015b828210610c9e57505050925f935b8651851015610722576106f38588611161565b519081811015610711575f52602052600160405f205b9401936106e0565b905f52602052600160405f20610709565b85907f000000000000000000000000000000000000000000000000000000000000000003610c765760035464ffffffffff811615610c5c575b506004549261076984611149565b9361077760405195866110ea565b80855260045f9081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b602087015b838310610c1f57505050505f84516107bd81611149565b956107cb60405197886110ea565b818752601f196107da83611149565b015f5b818110610bfc5750505f905b828210610b275750506001600160801b038216848111610b13578411610ae8575b5050508360081c5f52600260205260405f20600160ff86161b81541790556001600160a01b035f541692604051610840816110ce565b5f81525f60208201526040519161010083019583871067ffffffffffffffff881117610ad4576001600160a01b039660409492939452815260208101918583526040820185815260608301887f00000000000000000000000000000000000000000000000000000000000000001681528860808501917f0000000000000000000000000000000000000000000000000000000000000000151583526001600160801b0360a08701947f00000000000000000000000000000000000000000000000000000000000000001515865260c0880196875260e08801998a526040519c8d997f897f362b000000000000000000000000000000000000000000000000000000008b52602060048c0152816101448c019a511660248c0152511660448a0152511660648801525116608486015251151560a485015251151560c4840152519061012060e48401528151809152602061016484019201905f5b818110610a9f57505050819060208094516001600160a01b03815116610104850152015161012483015203815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1928315610a94575f93610a3c575b50907f28b58397e03322f670d6b223cc863f8c148e368b8b615412e6798a641a22842d60406020958594825191825287820152a3604051908152f35b939250906020843d602011610a8c575b81610a59602093836110ea565b810103126100fc5792519192907f28b58397e03322f670d6b223cc863f8c148e368b8b615412e6798a641a22842d610a00565b3d9150610a4c565b6040513d5f823e3d90fd5b825180516001600160801b0316855260209081015164ffffffffff168186015289955060409094019390920191600101610999565b634e487b7160e01b5f52604160045260245ffd5b6001600160801b0391610aff83925f190188611161565b51930316818351160116905284808061080a565b634e487b7160e01b5f52600160045260245ffd5b9092610b4867ffffffffffffffff610b3f8685611161565b51511687611189565b6001600160801b038111610bd1576001600160801b038091169164ffffffffff6020610b748887611161565b5101511660405190610b85826110ce565b8482526020820152610b97878c611161565b52610ba2868b611161565b5016016001600160801b038111610bbd5792600101906107e9565b634e487b7160e01b5f52601160045260245ffd5b7f4916adce000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b602090604051610c0b816110ce565b5f81525f8382015282828c010152016107dd565b600160208192604051610c31816110ce565b64ffffffffff865467ffffffffffffffff8116835260401c16838201528152019201920191906107a6565b64ffffffffff19164264ffffffffff16176003558461075b565b7ffe365d76000000000000000000000000000000000000000000000000000000005f5260045ffd5b81358152602091820191016106d2565b847fcd4c86cc000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7f99657b41000000000000000000000000000000000000000000000000000000005f524260045264ffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660245260445ffd5b7f36d385ef000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346100fc575f3660031901126100fc5760206040517f000000000000000000000000000000000000000000000000000000000000000015158152f35b346100fc575f3660031901126100fc5760206040517f000000000000000000000000000000000000000000000000000000000000000015158152f35b346100fc5760403660031901126100fc57610ded6110b8565b6024356001600160801b0381168091036100fc576001600160a01b035f54163381036103a9575064ffffffffff6003541680151580611007575b80610ff8575b610f9e57506040515f806001600160a01b0360208401957fa9059cbb000000000000000000000000000000000000000000000000000000008752169485602485015284604485015260448452610e846064856110ea565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001693519082855af13d15610f92573d67ffffffffffffffff8111610ad457610ef79160405191610ee76020601f19601f84011601846110ea565b82523d5f602084013e5b83611237565b8051908115159182610f6e575b5050610f4357507f2e9d425ba8b27655048400b366d7b6a1f7180ebdb088e06bb7389704860ffe1f60206001600160a01b035f541692604051908152a3005b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b81925090602091810103126100fc57602001518015908115036100fc578480610f04565b610ef790606090610ef1565b7f6df0cfdb000000000000000000000000000000000000000000000000000000005f524260045264ffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660245260445260645ffd5b5061100161110c565b15610e2d565b5062093a80810164ffffffffff8111610bbd5764ffffffffff164211610e27565b346100fc575f3660031901126100fc57610496907f000000000000000000000000000000000000000000000000000000000000000060208201526020815261048a6040826110ea565b9190916020815282518060208301525f5b8181106110a2575060409293505f838284010152601f8019910116010190565b8060208092870101516040828601015201611082565b600435906001600160a01b03821682036100fc57565b6040810190811067ffffffffffffffff821117610ad457604052565b90601f8019910116810190811067ffffffffffffffff821117610ad457604052565b64ffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168015159081611141575090565b905042101590565b67ffffffffffffffff8111610ad45760051b60200190565b80518210156111755760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b9091905f198382098382029182808310920391808303921461122657670de0b6b3a76400008210156111f6577faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106699394670de0b6b3a7640000910990828211900360ee1b910360121c170290565b84907f5173648d000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b5050670de0b6b3a764000090049150565b90611274575080511561124c57805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b815115806112ba575b611285575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b1561127d56fea164736f6c634300081a000aa164736f6c634300081a000a"; bytes public constant BYTECODE_NFT_DESCRIPTOR = hex"60808060405234601557615f8d908161001a8239f35b5f80fdfe6102406040526004361015610012575f80fd5b5f3560e01c63e9dc637514610025575f80fd5b346141bc5760403660031901126141bc576001600160a01b036004351680600435036141bc576103e06040525f61024081905260606102608190526102808290526102a08290526102c08190526102e0819052610320819052610340819052610360819052610380526103a08190526103c0526103008190526100b6906100ad600435614824565b61032052614b1e565b61034052610300516040517feac8f5b80000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa9081156145b8575f91614681575b506001600160a01b0361012791168061024052614c1a565b61026052610300516040517fa80fc0710000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa80156145b8576fffffffffffffffffffffffffffffffff915f91614662575b501661028052610300516040517fad35efd40000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa80156145b8575f90614625575b6101f59150614dbc565b61036052610300516040517f4869e12d0000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa9081156145b8575f916145f6575b50610280516fffffffffffffffffffffffffffffffff1680156145e2576fffffffffffffffffffffffffffffffff612710819302160416610160610240015260405160208101904682526bffffffffffffffffffffffff1960043560601b1660408201526024356054820152605481526102c9607482614710565b51902061040a60028061016861ffff8560101c160693600161031c63ffffffff601e61031482601461030c82604660ff6050818d60081c16069b16069d166154e9565b9701166154e9565b9801166154e9565b60246040519788947f68736c2800000000000000000000000000000000000000000000000000000000602087015261035d815180926020868a0191016146ca565b85017f2c00000000000000000000000000000000000000000000000000000000000000838201526103988251809360206025850191016146ca565b01017f252c000000000000000000000000000000000000000000000000000000000000838201526103d38251809360206003850191016146ca565b01017f2529000000000000000000000000000000000000000000000000000000000000838201520301601d19810184520182614710565b6104446fffffffffffffffffffffffffffffffff604061024001511660ff61043d6001600160a01b036102405116614ebc565b1690615022565b9061045a6001600160a01b036102405116614b1e565b6020610240015190602460206001600160a01b0360c0610240015116604051928380927fbc2be1be000000000000000000000000000000000000000000000000000000008252823560048301525afa80156145b8576024915f916145c3575b5060206001600160a01b0360c0610240015116604051938480927f9067b677000000000000000000000000000000000000000000000000000000008252823560048301525afa80156145b85764ffffffffff8091610521945f91614589575b50169116615318565b610340516103a05190939091906105ac600161054a6064610543818806615994565b96046154e9565b6020604051968261056489945180928580880191016146ca565b8301610578825180938580850191016146ca565b01017f2500000000000000000000000000000000000000000000000000000000000000815203601e19810186520184614710565b61016061024001519361012061024001519760e061024001519760405161016052610140610160510161016051811067ffffffffffffffff821117614575576040526101605152602061016051015260406101605101526060610160510152608061016051015260a061016051015260c061016051015260e06101605101526101006101605101526101206101605101526040516101c0810181811067ffffffffffffffff82111761457557604052606081525f60208201525f60408201526060808201525f6080820152606060a08201525f60c08201525f60e082015260606101008201525f6101208201525f61014082015260606101608201525f6101808201525f6101a082015260a06101605101516108eb6109ca60046007602760586106e260c0610160510151610160515190615a95565b60b76106ed5f615d85565b985f6102205260206102205261071560405161070c6102205182614710565b5f8152846157b3565b1561456b57601b60909a5b6107298c6154e9565b906040519b8c9889937f3c672069643d220000000000000000000000000000000000000000000000000061022051860152835161076f81846102205188019801886146ca565b8b017f222066696c6c3d2223666666223e000000000000000000000000000000000000838201527f3c726563742077696474683d220000000000000000000000000000000000000060358201526107d282518093604284019061022051016146ca565b0101917f22206865696768743d22313030222066696c6c2d6f7061636974793d222e3033858401527f222072783d223135222072793d22313522207374726f6b653d22236666662220603b8401527f7374726f6b652d6f7061636974793d222e3122207374726f6b652d7769647468605b8401527f3d2234222f3e0000000000000000000000000000000000000000000000000000607b8401527f3c7465787420783d2232302220793d2233342220666f6e742d66616d696c793d60818401527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f7370616365222060a18401527f666f6e742d73697a653d2232327078223e00000000000000000000000000000060c184015251809360d28401906146ca565b0101661e17ba32bc3a1f60c91b838201527f3c7465787420783d2232302220793d2237322220666f6e742d66616d696c793d60be8201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f7370616365222060de8201527f666f6e742d73697a653d2232367078223e00000000000000000000000000000060fe8201526109858251809361010f84019061022051016146ca565b0101661e17ba32bc3a1f60c91b838201526109ac82518093605f84019061022051016146ca565b0101631e17b39f60e11b838201520301601b19810184520182614710565b6101008301526101208201526101206101605101516108eb610a3860046007602760586040516109fd6102205182614710565b5f815260b7610a0c6001615d85565b98601b6028610a1a8c615e90565b610a2384615f08565b8082111561456457505b019a6107298c6154e9565b61016083015261018082015260206101605101516108eb610a796004600760276058604051610a6a6102205182614710565b5f815260b7610a0c6002615d85565b8252602082015260286080610160510151604051610a9a6102205182614710565b5f81526108eb610ae46004600760276058610ab56003615d85565b9660b7610ac189615e90565b610aca8b615f08565b8082111561455c5750995b601b8c8c019a6107298c6154e9565b60a085015260c0840152602083015101016101208201510161018082015101603081016080830152602f19906103e8030160011c8061014083015261012082015101601081016101a083015261018082015101610220518101604083015260106102205191602084015101010160e0820152610b7361010082015161016083015183519060a085015192614fb5565b60608201526101006101208190526040516101a0819052610b949190614710565b60c76101a051527f3c726563742077696474683d223130302522206865696768743d223130302522610220516101a05101527f2066696c7465723d2275726c28234e6f69736529222f3e3c7265637420783d2260406101a05101527f37302220793d223730222077696474683d2238363022206865696768743d223860606101a05101527f3630222066696c6c3d2223666666222066696c6c2d6f7061636974793d222e3060806101a05101527f33222072783d223435222072793d22343522207374726f6b653d22236666662260a06101a05101527f207374726f6b652d6f7061636974793d222e3122207374726f6b652d7769647460c06101a05101527f683d2234222f3e0000000000000000000000000000000000000000000000000060e06101a05101526101605151610120610160510151906060830151610140525f610200526060610200526040516101e052610cf6610200516101e051614710565b60336101e051527f3c636972636c652069643d22476c6f772220723d22353030222066696c6c3d22610220516101e05101527f75726c282352616469616c476c6f7729222f3e0000000000000000000000000060406101e051015261014060405190610d628183614710565b61011c82527f3c66696c7465722069643d224e6f697365223e3c6665466c6f6f6420783d2230610220518301527f2220793d2230222077696474683d223130302522206865696768743d2231303060408301527f252220666c6f6f642d636f6c6f723d2268736c283233302c3231252c31312529610200518301527f2220666c6f6f642d6f7061636974793d22312220726573756c743d22666c6f6f60808301527f6446696c6c222f3e3c666554757262756c656e6365206261736546726571756560a08301527f6e63793d222e3422206e756d4f6374617665733d22332220726573756c743d2260c08301527f4e6f6973652220747970653d226672616374616c4e6f697365222f3e3c66654260e08301527f6c656e6420696e3d224e6f6973652220696e323d22666c6f6f6446696c6c2220610120518301527f6d6f64653d22736f66742d6c69676874222f3e3c2f66696c7465723e000000006101208301525f6101c0526103a06101c0526119416118bc6073606b60405196610eeb6101c05189614710565b61037b88527f3c706174682069643d224c6f676f222066696c6c3d2223666666222066696c6c610220518901527f2d6f7061636974793d222e312220643d226d3133332e3535392c3132342e303360408901527f34632d2e3031332c322e3431322d312e3035392c342e3834382d322e3932332c610200518901527f362e3430322d322e3535382c312e3831392d352e3136382c332e3433392d372e60808901527f3838382c342e3939362d31342e34342c382e3236322d33312e3034372c31322e60a08901527f3536352d34372e3637342c31322e3536392d382e3835382e3033362d31372e3860c08901527f33382d312e3237322d32362e3332382d332e3636332d392e3830362d322e373660e08901527f362d31392e3038372d372e3131332d32372e3536322d31322e3737382d31332e610120518901527f3834322d382e3032352c392e3436382d32382e3630362c31362e3135332d33356101208901527f2e323635683063322e3033352d312e3833382c342e3235322d332e3534362c36868901527f2e3436332d352e323234683063362e3432392d352e3635352c31362e3231382d6101608901527f322e3833352c32302e3335382c342e31372c342e3134332c352e3035372c382e6101808901527f3831362c392e3634392c31332e39322c31332e373334682e30333763352e37336101a08901527f362c362e3436312c31352e3335372d322e3235332c392e33382d382e34382c306101c08901527f2c302d332e3531352d332e3531352d332e3531352d332e3531352d31312e34396101e08901527f2d31312e3437382d35322e3635362d35322e3636342d36342e3833372d36342e6102008901527f3833376c2e3034392d2e303337632d312e3732352d312e3630362d322e3731396102208901527f2d332e3834372d322e3735312d362e3230346830632d2e3034362d322e3337356102408901527f2c312e3036322d342e3538322c322e3732362d362e32323968306c2e3138352d6102608901527f2e3134386830632e3039392d2e3036322c2e3232322d2e3134382c2e33372d2e6102808901527f323539683063322e30362d312e3336322c332e3935312d322e3632312c362e306102a08901527f34342d332e3834324335372e3736332d332e3437332c39372e37362d322e33346102c08901527f312c3132382e3633372c31382e3333326331362e3637312c392e3934362d32366102e08901527f2e3334342c35342e3831332d33382e3635312c34302e3139392d362e3239392d6103008901527f362e3039362d31382e3036332d31372e3734332d31392e3636382d31382e38316103208901527f312d362e3031362d342e3034372d31332e3036312c342e3737362d372e3735326103408901527f2c392e3735316c36382e3235342c36382e33373163312e3732342c312e3630316103608901527f2c322e3731342c332e38342c322e3733382c362e3139325a222f3e00000000006103808901525f6101805260a06101805260405160a0526113506101805160a051614710565b607560a051527f3c706174682069643d22466c6f6174696e6754657874222066696c6c3d226e6f6102205160a05101527f6e652220643d224d313235203435683735307338302030203830203830763735604060a05101527f307330203830202d3830203830682d373530732d38302030202d3830202d38306102005160a05101527f762d3735307330202d3830203830202d3830222f3e0000000000000000000000608060a051015261193c60146022611409615a5a565b9360a2604051957f3c72616469616c4772616469656e742069643d2252616469616c476c6f77223e610220518801527f3c73746f70206f66667365743d223025222073746f702d636f6c6f723d220000604088015261153e6025603589605e8751956102205189019661147f818486018a6146ca565b83017f222073746f702d6f7061636974793d222e36222f3e0000000000000000000000838201528f7f3c73746f70206f66667365743d2231303025222073746f702d636f6c6f723d22908201526114e282518093609384019061022051016146ca565b01017f222073746f702d6f7061636974793d2230222f3e000000000000000000000000838201527f3c2f72616469616c4772616469656e743e00000000000000000000000000000060498201520301600581018a520188614710565b61165585602361154c615a5a565b6040519b8c917f3c6c696e6561724772616469656e742069643d2253616e64546f70222078313d610220518401527f223025222079313d223025223e0000000000000000000000000000000000000060408401527f3c73746f70206f66667365743d223025222073746f702d636f6c6f723d220000604d84015288516115d5818486018a6146ca565b83016211179f60e91b838201527f3c73746f70206f66667365743d2231303025222073746f702d636f6c6f723d22606e82015261161e82518093608e84019061022051016146ca565b01016211179f60e91b83820152701e17b634b732b0b923b930b234b2b73a1f60791b60268201520301600b1981018b520189614710565b6117df60726023611664615a5a565b6040519c8d917f3c6c696e6561724772616469656e742069643d2253616e64426f74746f6d2220610220518401527f78313d2231303025222079313d2231303025223e00000000000000000000000060408401527f3c73746f70206f66667365743d22313025222073746f702d636f6c6f723d220060548401526116f3815180928486019061022051016146ca565b82016211179f60e91b828201527f3c73746f70206f66667365743d2231303025222073746f702d636f6c6f723d22607682015288519061173782609683018a6146ca565b01016211179f60e91b838201527f3c616e696d617465206174747269627574654e616d653d22783122206475723d60268201527f2236732220726570656174436f756e743d22696e646566696e6974652220766160468201527f6c7565733d223330253b3630253b313230253b3630253b3330253b222f3e00006066820152701e17b634b732b0b923b930b234b2b73a1f60791b60848201520301605281018c52018a614710565b6117e7615a5a565b906040519a8b947f3c6c696e6561724772616469656e742069643d22486f7572676c617373537472610220518701527f6f6b6522206772616469656e745472616e73666f726d3d22726f74617465283960408701527f302922206772616469656e74556e6974733d227573657253706163654f6e5573610200518701527f65223e000000000000000000000000000000000000000000000000000000000060808701527f3c73746f70206f66667365743d22353025222073746f702d636f6c6f723d22006083870152518092858701906146ca565b83016211179f60e91b838201527f3c73746f70206f66667365743d22383025222073746f702d636f6c6f723d220060a58201526119058251809360c484019061022051016146ca565b01016211179f60e91b83820152701e17b634b732b0b923b930b234b2b73a1f60791b60258201520301600b19810187520185614710565b614fb5565b60e05261195561194f614d46565b856157b3565b938415614541575b5060c061010081905260405191906119759083614710565b609082527f3c7061746820643d224d2035302c3336302061203330302c333030203020312c610220518301527f31203630302c302061203330302c333030203020312c31202d3630302c30222060408301527f66696c6c3d2223666666222066696c6c2d6f7061636974793d222e3032222073610200518301527f74726f6b653d2275726c2823486f7572676c6173735374726f6b65292220737460808301527f726f6b652d77696474683d2234222f3e00000000000000000000000000000000610180518301526102c060405160c052611a528160c051614710565b61029860c051527f3c7061746820643d226d3536362c3136312e323031762d35332e39323463302d6102205160c05101527f31392e3338322d32322e3531332d33372e3536332d36332e3339382d35312e31604060c05101527f39382d34302e3735362d31332e3539322d39342e3934362d32312e3037392d316102005160c05101527f35322e3538372d32312e303739732d3131312e3833382c372e3438372d313532608060c05101527f2e3630322c32312e303739632d34302e3839332c31332e3633362d36332e34316101805160c05101527f332c33312e3831362d36332e3431332c35312e3139387635332e39323463302c6101005160c05101527f31372e3138312c31372e3730342c33332e3432372c35302e3232332c34362e3360e060c05101527f3934763238342e383039632d33322e3531392c31322e39362d35302e3232332c6101205160c05101527f32392e3230362d35302e3232332c34362e3339347635332e39323463302c313961012060c05101527f2e3338322c32322e35322c33372e3536332c36332e3431332c35312e3139382c8260c05101527f34302e3736332c31332e3539322c39342e3935342c32312e3037392c3135322e61016060c05101527f3630322c32312e303739733131312e3833312d372e3438372c3135322e35383761018060c05101527f2d32312e3037396334302e3838362d31332e3633362c36332e3339382d33312e6101a060c05101527f3831362c36332e3339382d35312e313938762d35332e39323463302d31372e316101c060c05101527f39362d31372e3730342d33332e3433352d35302e3232332d34362e34303156326101e060c05101527f30372e3630336333322e3531392d31322e3936372c35302e3232332d32392e3261020060c05101527f30362c35302e3232332d34362e3430315a6d2d3334372e3436322c35372e373961022060c05101527f336c3133302e3935392c3133312e3032372d3133302e3935392c3133312e303161024060c05101527f33563231382e3939345a6d3236322e3932342e303232763236322e3031386c2d61026060c05101527f3133302e3933372d3133312e3030362c3133302e3933372d3133312e3031335a61028060c05101527f222066696c6c3d2223313631383232223e3c2f706174683e00000000000000006102a060c0510152855f1461432c57604051611dcd6102205182614710565b5f8152955b156141d957604051611de66101e082614710565b6101b181527f3c7061746820643d226d3438312e34362c3438312e35347638312e3031632d32610220518201527f2e33352e37372d342e38322c312e35312d372e33392c322e32332d33302e332c60408201527f382e35342d37342e36352c31332e39322d3132342e30362c31332e39322d3533610200518201527f2e362c302d3130312e32342d362e33332d3133312e34372d31362e3136762d3860808201527f316c34362e332d34362e3331683137302e33336c34362e32392c34362e33315a610180518201527f222066696c6c3d2275726c282353616e64426f74746f6d29222f3e3c70617468610100518201527f20643d226d3433352e31372c3433352e323363302c312e31372d2e34362c322e60e08201527f33322d312e33332c332e34342d372e31312c392e30382d34312e39332c31352e610120518201527f39382d38332e38312c31352e3938732d37362e372d362e392d38332e38322d316101208201527f352e3938632d2e38372d312e31322d312e33332d322e32372d312e33332d332e838201527f3434762d2e30346c382e33342d382e33352e30312d2e30316331332e37322d366101608201527f2e35312c34322e39352d31312e30322c37362e382d31312e30327336322e39376101808201527f2c342e34392c37362e37322c31316c382e34322c382e34325a222066696c6c3d6101a08201527f2275726c282353616e64546f7029222f3e0000000000000000000000000000006101c0820152905b6040519261201f6107e085614710565b6107a7845261022080517f3c672066696c6c3d226e6f6e6522207374726f6b653d2275726c2823486f7572908601527f676c6173735374726f6b652922207374726f6b652d6c696e656361703d22726f60408087019190915261020080517f756e6422207374726f6b652d6d697465726c696d69743d22313022207374726f908801527f6b652d77696474683d2234223e3c7061746820643d226d3536352e3634312c31608088015261018080517f30372e323863302c392e3533372d352e35362c31382e3632392d31352e36373690890152610100517f2c32362e393733682d2e303233632d392e3230342c372e3539362d32322e3139908901527f342c31342e3536322d33382e3139372c32302e3539322d33392e3530342c313460e089015261012080517f2e3933362d39372e3332352c32342e3335352d3136312e3733332c32342e3335908a01527f352d39302e34382c302d3136372e3934382d31382e3538322d3139392e393533908901527f2d34342e393438682d2e303233632d31302e3131352d382e3334342d31352e36948801949094527f37362d31372e3433372d31352e3637362d32362e3937332c302d33392e3733356101608801527f2c39362e3535342d37312e3932312c3231352e3635322d37312e393231733231938701939093527f352e3632392c33322e3138352c3231352e3632392c37312e3932315a222f3e3c6101a08701527f7061746820643d226d3133342e33362c3136312e32303363302c33392e3733356101c0808801919091527f2c39362e3535342c37312e3932312c3231352e3635322c37312e3932317332316101e08801527f352e3632392d33322e3138362c3231352e3632392d37312e393231222f3e3c6c938701939093527f696e652078313d223133342e3336222079313d223136312e323033222078323d828701527f223133342e3336222079323d223130372e3238222f3e3c6c696e652078313d226102408701527f3536352e3634222079313d223136312e323033222078323d223536352e3634226102608701527f2079323d223130372e3238222f3e3c6c696e652078313d223138342e353834226102808701527f2079313d223230362e383233222078323d223138342e353835222079323d22356102a08701527f33372e353739222f3e3c6c696e652078313d223231382e313831222079313d22938601939093527f3231382e313138222078323d223231382e313831222079323d223536322e35336102e08601527f37222f3e3c6c696e652078313d223438312e383138222079313d223231382e316103008601527f3432222078323d223438312e383139222079323d223536322e343238222f3e3c6103208601527f6c696e652078313d223531352e343135222079313d223230372e3335322220786103408601527f323d223531352e343136222079323d223533372e353739222f3e3c70617468206103608601527f643d226d3138342e35382c3533372e353863302c352e34352c342e32372c313061038086015290517f2e36352c31322e30332c31352e3432682e303263352e35312c332e33392c3132908501527f2e37392c362e35352c32312e35352c392e34322c33302e32312c392e392c37386103c08501527f2e30322c31362e32382c3133312e38332c31362e32382c34392e34312c302c396103e08501527f332e37362d352e33382c3132342e30362d31332e39322c322e372d2e37362c356104008501527f2e32392d312e35342c372e37352d322e33352c382e37372d322e38372c31362e6104208501527f30352d362e30342c32312e35362d392e3433683063372e37362d342e37372c316104408501527f322e30342d392e39372c31322e30342d31352e3432222f3e3c7061746820643d6104608501527f226d3138342e3538322c3439322e363536632d33312e3335342c31322e3438356104808501527f2d35302e3232332c32382e35382d35302e3232332c34362e3134322c302c392e6104a08501527f3533362c352e3536342c31382e3632372c31352e3637372c32362e393639682e6104c08501527f30323263382e3530332c372e3030352c32302e3231332c31332e3436332c33346104e08501527f2e3532342c31392e3135392c392e3939392c332e3939312c32312e3236392c376105008501527f2e3630392c33332e3539372c31302e3738382c33362e34352c392e3430372c386105208501527f322e3138312c31352e3030322c3133312e3833352c31352e3030327339352e336105408501527f36332d352e3539352c3133312e3830372d31352e3030326331302e3834372d326105608501527f2e37392c32302e3836372d352e3932362c32392e3932342d392e3334392c312e6105808501527f3234342d2e3436372c322e3437332d2e3934322c332e3637332d312e3432342c6105a08501527f31342e3332362d352e3639362c32362e3033352d31322e3136312c33342e35326105c08501527f342d31392e313733682e3032326331302e3131342d382e3334322c31352e36376105e08501527f372d31372e3433332c31352e3637372d32362e3936392c302d31372e3536322d6106008501527f31382e3836392d33332e3636352d35302e3232332d34362e3135222f3e3c70616106208501527f746820643d226d3133342e33362c3539322e373263302c33392e3733352c39366106408501527f2e3535342c37312e3932312c3231352e3635322c37312e393231733231352e366106608501527f32392d33322e3138362c3231352e3632392d37312e393231222f3e3c6c696e656106808501527f2078313d223133342e3336222079313d223539322e3732222078323d223133346106a08501527f2e3336222079323d223533382e373937222f3e3c6c696e652078313d223536356106c08501527f2e3634222079313d223539322e3732222078323d223536352e3634222079323d6106e08501527f223533382e373937222f3e3c706f6c796c696e6520706f696e74733d223438316107008501527f2e383232203438312e393031203438312e373938203438312e383737203438316107208501527f2e373735203438312e383534203335302e303135203335302e303236203231386107408501527f2e313835203231382e313239222f3e3c706f6c796c696e6520706f696e74733d6107608501527f223231382e313835203438312e393031203231382e323331203438312e3835346107808501527f203335302e303135203335302e303236203438312e383232203231382e3135326107a08501527f222f3e3c2f673e000000000000000000000000000000000000000000000000006107c0850152905181517f3c672069643d22486f7572676c617373223e00000000000000000000000000009082015284519151909788959092916129ee9183916032890191016146ca565b840160c051519060328101826102205160c0510191612a0c926146ca565b016032018082518093610220510191612a24926146ca565b018082518093610220510191612a39926146ca565b018082518093610220510191612a4e926146ca565b01631e17b39f60e11b815203601b1981018452600401612a6e9084614710565b60405160805261022051608051017f3c646566733e000000000000000000000000000000000000000000000000000090526101e0515160805160260181610220516101e0510191612abe926146ca565b60805101815191826026830191610220510191612ada926146ca565b016026018082518093610220510191612af2926146ca565b0160a051519080826102205160a0510191612b0c926146ca565b0160e051519080826102205160e0510191612b26926146ca565b018082518093610220510191612b3b926146ca565b01610140515190808261022051610140510191612b57926146ca565b017f3c2f646566733e000000000000000000000000000000000000000000000000008152608051900360181981016080515260070160805190612b9991614710565b6101605160e0015190610160516101000151916101605160400151906101605160600151612bc78583615cd9565b916040958651612bd78882614710565b600581526102205181017f2d31303025000000000000000000000000000000000000000000000000000000905287519485916102205183017f3c74657874506174682073746172744f66667365743d220000000000000000009052805190816037850191610220510191612c4a926146ca565b7f2220687265663d2223466c6f6174696e6754657874222066696c6c3d222366666037918401918201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e0000000000000000006101098201528151610220519092612d8e918491610120850191016146ca565b0160370160e981016a1e17ba32bc3a2830ba341f60a91b90520360e90160141981018552600b01612dbf9085614710565b612dc891615cd9565b928551612dd58782614710565b60028152610220518101947f3025000000000000000000000000000000000000000000000000000000000000865287519586926102205184017f3c74657874506174682073746172744f66667365743d22000000000000000000905251908160378501612e41926146ca565b7f2220687265663d2223466c6f6174696e6754657874222066696c6c3d222366666037918401918201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e0000000000000000006101098201528151610220519092612f85918491610120850191016146ca565b0160370160e981016a1e17ba32bc3a2830ba341f60a91b90520360e90160141981018552600b01612fb69085614710565b612fc08282615d40565b918651612fcd8882614710565b60048152610220518101937f2d35302500000000000000000000000000000000000000000000000000000000855288519485926102205184017f3c74657874506174682073746172744f66667365743d22000000000000000000905251908160378501613039926146ca565b7f2220687265663d2223466c6f6174696e6754657874222066696c6c3d222366666037918401918201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e000000000000000000610109820152815161022051909261317d918491610120850191016146ca565b0160370160e981016a1e17ba32bc3a2830ba341f60a91b90520360e90160141981018452600b016131ae9084614710565b6131b791615d40565b9085516131c48782614710565b60038152610220518101927f3530250000000000000000000000000000000000000000000000000000000000845287519384926102205184017f3c74657874506174682073746172744f66667365743d22000000000000000000905251908160378501613230926146ca565b7f2220687265663d2223466c6f6174696e6754657874222066696c6c3d222366666037918401918201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e0000000000000000006101098201528151610220519092613374918491610120850191016146ca565b0160370160e981016a1e17ba32bc3a2830ba341f60a91b90520360e90160141981018352600b016133a59083614710565b85519384936102205185017f3c7465787420746578742d72656e646572696e673d226f7074696d697a65537090528785017f656564223e0000000000000000000000000000000000000000000000000000009052805190816045870191610220510191613411926146ca565b840181519182604583019161022051019161342b926146ca565b016045018082518093610220510191613443926146ca565b018082518093610220510191613458926146ca565b01661e17ba32bc3a1f60c91b8152036018198101825260070161347b9082614710565b610140820151916101a08101519060408101519060e001519361349d906154e9565b916134a7906154e9565b906134b1906154e9565b936134bb906154e9565b8551948592610220518401947f3c75736520687265663d2223476c6f77222066696c6c2d6f7061636974793d2286528885017f2e39222f3e0000000000000000000000000000000000000000000000000000009052604585017f3c75736520687265663d2223476c6f772220783d22313030302220793d2231309052606585017f3030222066696c6c2d6f7061636974793d222e39222f3e0000000000000000009052607c85017f3c75736520687265663d22234c6f676f2220783d223137302220793d223137309052609c85017f22207472616e73666f726d3d227363616c65282e3629222f3e3c757365206872905260bc85017f65663d2223486f7572676c6173732220783d223135302220793d223930222074905260dc85017f72616e73666f726d3d22726f746174652831302922207472616e73666f726d2d905260fc85017f6f726967696e3d2235303020353030222f3e0000000000000000000000000000905261010e85017f3c75736520687265663d222350726f67726573732220783d2200000000000000905280519081610127870191610220510191613662926146ca565b840161012781016a11103c9e911b9c9811179f60a91b905261013281017f3c75736520687265663d22235374617475732220783d220000000000000000009052815191826101498301916102205101916136bb926146ca565b0161012701602281016a11103c9e911b9c9811179f60a91b9052602d81017f3c75736520687265663d2223416d6f756e742220783d220000000000000000009052815191826044830191610220510191613714926146ca565b01602201602281016a11103c9e911b9c9811179f60a91b9052602d81017f3c75736520687265663d22234475726174696f6e2220783d2200000000000000905281519182604683019161022051019161376c926146ca565b01602201602481016a11103c9e911b9c9811179f60a91b90520360240160141981018452600b0161379d9084614710565b83519283926102205184017f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323090528584017f30302f737667222077696474683d223130303022206865696768743d2231303090526102005184017f30222076696577426f783d2230203020313030302031303030223e000000000090526101a05151607b850181610220516101a0510191613837926146ca565b84016080515190607b810182610220516080510191613855926146ca565b01607b01808251809361022051019161386d926146ca565b0191829151809361387d926146ca565b017f3c2f7376673e0000000000000000000000000000000000000000000000000000815203601919810182526006016138b69082614710565b61038052610300518151610220517fb25645690000000000000000000000000000000000000000000000000000000090820190815260248035818401528252916001600160a01b03169061390b604482614710565b515a925f93928493fa61391c614793565b6102e0819052901580156103c0526141d15761022051818051810103126141bc5761022051015180151581036141bc575b15156102a052610260516103005182517fb971302a00000000000000000000000000000000000000000000000000000000815260248035600483015261022051919283919082906001600160a01b03165afa9081156141c7575f9161417b575b50600360236139be613ad693614b1e565b938161012061024001518780519788947f5b7b2274726169745f74797065223a224173736574222c2276616c7565223a2261022051870152613a0b815180928589019061022051016146ca565b85017f227d2c7b2274726169745f74797065223a2253656e646572222c2276616c75658382015262111d1160e91b61020051820152613a5682518093606384019061022051016146ca565b01017f227d2c7b2274726169745f74797065223a22537461747573222c2276616c75658382015262111d1160e91b6043820152613a9f82518093604684019061022051016146ca565b01017f227d5d0000000000000000000000000000000000000000000000000000000000838201520301601c19810184520182614710565b6103205161026051610340516102405191939291613afc906001600160a01b0316614b1e565b613b076024356154e9565b6102a051909190156140ef5761010051875190613b249082614710565b609b81527fe29aa0efb88f205741524e494e473a205472616e7366657272696e6720746865610220518201527f204e4654206d616b657320746865206e6577206f776e65722074686520726563888201527f697069656e74206f66207468652073747265616d2e205468652066756e647320610200518201527f617265206e6f74206175746f6d61746963616c6c792077697468647261776e2060808201527f666f72207468652070726576696f757320726563697069656e742e000000000061018051820152915b8751968794610220518601967f54686973204e465420726570726573656e74732061207061796d656e7420737488528a87017f7265616d20696e2061205361626c696572204c6f636b757020000000000000009052805190610220518101918060598a0190613c5c91856146ca565b7f20636f6e74726163742e20546865206f776e6572206f662074686973204e46546059918a01918201527f2063616e207769746864726177207468652073747265616d656420617373657460798201527f732c207768696368206172652064656e6f6d696e6174656420696e2000000000609982015284516102205186019691613cea8260b583018a6146ca565b01605901605c81017f2e5c6e5c6e2d2053747265616d2049443a200000000000000000000000000000905281519182606e830191610220510191613d2d926146ca565b01605c0190601282016302e3716960e51b905251918260168301613d50926146ca565b01601201600481016901020b2323932b9b99d160b51b905281519182600e830191610220510191613d80926146ca565b0160040190600a82016302e3716960e51b9052519182600e8301613da3926146ca565b01600a01600481016901020b2323932b9b99d160b51b905281519182600e830191610220510191613dd3926146ca565b01600401600a81017f5c6e5c6e00000000000000000000000000000000000000000000000000000000905281519182600e830191610220510191613e16926146ca565b01600a0103600401601f1981018452613e2f9084614710565b61032051613e3e6024356154e9565b855180916102205182019367029b0b13634b2b9160c51b8552805190816028850191610220510191613e6f926146ca565b8201602881017f2023000000000000000000000000000000000000000000000000000000000000905281519182602a830191610220510191613eb0926146ca565b0160280103600201601f1981018252613ec99082614710565b61038051613ed690615648565b9286519586956102205187017f7b2261747472696275746573223a000000000000000000000000000000000000905280519081602e890191610220510191613f1d926146ca565b860190602e82017f2c226465736372697074696f6e223a22000000000000000000000000000000009052519182603e8301613f57926146ca565b01602e0190601082017f222c2265787465726e616c5f75726c223a2268747470733a2f2f7361626c69659052603082017f722e636f6d222c226e616d65223a2200000000000000000000000000000000009052519182603f8301613fba926146ca565b01601001602f81017f222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b62619052604f81017f736536342c0000000000000000000000000000000000000000000000000000009052815191826054830191610220510191614024926146ca565b01602f01602581017f227d000000000000000000000000000000000000000000000000000000000000905203602501601d19810182526002016140679082614710565b6102c081905261407690615648565b90805180926102205182017f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000905280519081603d8401916102205101916140bc926146ca565b810103603d01601f19810183526140d39083614710565b5180916102205182526102205182016140eb916146eb565b0390f35b86516140fc608082614710565b605b81527fe29d95494e464f3a2054686973204e4654206973206e6f6e2d7472616e736665610220518201527f7261626c652e2049742063616e6e6f7420626520736f6c64206f72207472616e888201527f7366657272656420746f20616e6f74686572206163636f756e742e00000000006102005182015291613bed565b9050610220513d61022051116141c0575b6141968183614710565b816102205191810103126141bc57516001600160a01b03811681036141bc5760036139ad565b5f80fd5b503d61418c565b83513d5f823e3d90fd5b50600161394d565b6040516141e861012082614710565b60f881527f3c7061746820643d226d3438312e34362c3530342e3130317635382e34343963610220518201527f2d322e33352e37372d342e38322c312e35312d372e33392c322e32332d33302e60408201527f332c382e35342d37342e36352c31332e39322d3132342e30362c31332e39322d610200518201527f35332e362c302d3130312e32342d362e33332d3133312e34372d31362e31367660808201527f2d35382e343339683236322e39325a222066696c6c3d2275726c282353616e64610180518201527f426f74746f6d29222f3e3c656c6c697073652063783d22333530222063793d22610100518201527f3530342e313031222072783d223133312e343632222072793d2232382e31303860e08201527f222066696c6c3d2275726c282353616e64546f7029222f3e0000000000000000610120518201529061200f565b60405161433b6101c082614710565b61019981527f3c706f6c79676f6e20706f696e74733d22333530203335302e30323620343135610220518201527f2e3033203238342e39373820323835203238342e39373820333530203335302e60408201527f303236222066696c6c3d2275726c282353616e64426f74746f6d29222f3e3c70610200518201527f61746820643d226d3431362e3334312c3238312e39373563302c2e3931342d2e60808201527f3335342c312e3830392d312e3033352c322e36382d352e3534322c372e303736610180518201527f2d33322e3636312c31322e34352d36352e32382c31322e34352d33322e363234610100518201527f2c302d35392e3733382d352e3337342d36352e32382d31322e34352d2e36383160e08201527f2d2e3837322d312e3033352d312e3736372d312e3033352d322e36382c302d2e610120518201527f3931342e3335342d312e3830382c312e3033352d322e3637362c352e3534322d6101208201527f372e3037362c33322e3635362d31322e34352c36352e32382d31322e34352c33838201527f322e3631392c302c35392e3733382c352e3337342c36352e32382c31322e34356101608201527f2e3638312e3836372c312e3033352c312e3736322c312e3033352c322e3637366101808201527f5a222066696c6c3d2275726c282353616e64546f7029222f3e000000000000006101a082015295611dd2565b61455591945061454f614d81565b906157b3565b925f61195d565b905099610ad5565b9050610a2d565b601b60d09a610720565b634e487b7160e01b5f52604160045260245ffd5b6145ab915060203d6020116145b1575b6145a38183614710565b81019061475a565b5f610518565b503d614599565b6040513d5f823e3d90fd5b6145dc915060203d6020116145b1576145a38183614710565b5f6104b9565b634e487b7160e01b5f52601260045260245ffd5b614618915060203d60201161461e575b6146108183614710565b810190614732565b5f61024e565b503d614606565b506020813d60201161465a575b8161463f60209383614710565b810103126141bc575160058110156141bc576101f5906101eb565b3d9150614632565b61467b915060203d60201161461e576146108183614710565b5f610191565b90506020813d6020116146c2575b8161469c60209383614710565b810103126141bc57516001600160a01b03811681036141bc576001600160a01b0361010f565b3d915061468f565b5f5b8381106146db5750505f910152565b81810151838201526020016146cc565b90602091614704815180928185528580860191016146ca565b601f01601f1916010190565b90601f8019910116810190811067ffffffffffffffff82111761457557604052565b908160209103126141bc57516fffffffffffffffffffffffffffffffff811681036141bc5790565b908160209103126141bc575164ffffffffff811681036141bc5790565b67ffffffffffffffff811161457557601f01601f191660200190565b3d156147bd573d906147a482614777565b916147b26040519384614710565b82523d5f602084013e565b606090565b6020818303126141bc5780519067ffffffffffffffff82116141bc570181601f820112156141bc5780516147f581614777565b926148036040519485614710565b818452602082840101116141bc5761482191602080850191016146ca565b90565b6001600160a01b0316604051906395d89b4160e01b82525f82600481845afa9182156145b8575f92614afa575b5060409161489483516148648582614710565b600e81527f5341422d4c4f434b55502d4c494e0000000000000000000000000000000000006020820152826157b3565b8015614ab5575b156148db5750506148ae81519182614710565b600d81527f4c6f636b7570204c696e65617200000000000000000000000000000000000000602082015290565b61491a83516148ea8582614710565b600e81527f5341422d4c4f434b55502d44594e0000000000000000000000000000000000006020820152826157b3565b8015614a70575b1561496157505061493481519182614710565b600e81527f4c6f636b75702044796e616d6963000000000000000000000000000000000000602082015290565b6149a083516149708582614710565b600e81527f5341422d4c4f434b55502d5452410000000000000000000000000000000000006020820152826157b3565b8015614a2b575b156149e75750506149ba81519182614710565b600f81527f4c6f636b7570205472616e636865640000000000000000000000000000000000602082015290565b614a279083519384937f7498e3a50000000000000000000000000000000000000000000000000000000085526004850152602484015260448301906146eb565b0390fd5b50614a6b8351614a3b8582614710565b601181527f5341422d56322d4c4f434b55502d5452410000000000000000000000000000006020820152826157b3565b6149a7565b50614ab08351614a808582614710565b601181527f5341422d56322d4c4f434b55502d44594e0000000000000000000000000000006020820152826157b3565b614921565b50614af58351614ac58582614710565b601181527f5341422d56322d4c4f434b55502d4c494e0000000000000000000000000000006020820152826157b3565b61489b565b614b179192503d805f833e614b0f8183614710565b8101906147c2565b905f614851565b6001600160a01b03168060405191614b37606084614710565b602a8352602083016040368237835115614c065760309053825160011015614c06576078602184015360295b60018111614ba45750614b74575090565b7fe22e27eb000000000000000000000000000000000000000000000000000000005f52600452601460245260445ffd5b90600f81166010811015614c06577f3031323334353637383961626364656600000000000000000000000000000000901a614bdf83866157e0565b5360041c908015614bf2575f1901614b63565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f809160405160208101906395d89b4160e01b825260048152614c3e602482614710565b51915afa614c4a614793565b90158015614d3a575b614cfe5780602080614c6a935183010191016147c2565b601e8151115f14614cb15750604051614c84604082614710565b600b81527f4c6f6e672053796d626f6c000000000000000000000000000000000000000000602082015290565b614cba816157f1565b15614cc25790565b50604051614cd1604082614710565b601281527f556e737570706f727465642053796d626f6c0000000000000000000000000000602082015290565b50604051614d0d604082614710565b600581527f4552433230000000000000000000000000000000000000000000000000000000602082015290565b50604081511115614c53565b60405190614d55604083614710565b600782527f536574746c6564000000000000000000000000000000000000000000000000006020830152565b60405190614d90604083614710565b600882527f4465706c657465640000000000000000000000000000000000000000000000006020830152565b6005811015614ea85760048103614dd65750614821614d81565b60038103614e1a5750604051614ded604082614710565b600881527f43616e63656c6564000000000000000000000000000000000000000000000000602082015290565b60018103614e5e5750604051614e31604082614710565b600981527f53747265616d696e670000000000000000000000000000000000000000000000602082015290565b600203614e6d57614821614d46565b604051614e7b604082614710565b600781527f50656e64696e6700000000000000000000000000000000000000000000000000602082015290565b634e487b7160e01b5f52602160045260245ffd5b5f809160405160208101907f313ce56700000000000000000000000000000000000000000000000000000000825260048152614ef9602482614710565b51915afa614f05614793565b9080614f34575b15614f2f576020818051810103126141bc576020015160ff811681036141bc5790565b505f90565b506020815114614f0c565b60405190614f4e604083614710565b600482527f2667743b000000000000000000000000000000000000000000000000000000006020830152565b60405190614f89604083614710565b600482527f266c743b000000000000000000000000000000000000000000000000000000006020830152565b90614fe09493615011602061502095615003828096816040519c8d8b83829d519485930191016146ca565b8901614ff4825180938580850191016146ca565b010191828151948592016146ca565b0191828151948592016146ca565b0103601f198101845283614710565b565b9081156152f757806152e757505b806001811015615099575050615044614f7a565b614821600260206040518461506282965180928580860191016146ca565b81017f2031000000000000000000000000000000000000000000000000000000000000838201520301601d19810184520182614710565b66038d7ea4c680001115615289576040519060a0820182811067ffffffffffffffff821117614575576040526020916040516150d58482614710565b5f8152815260409182516150e98482614710565b600181527f4b00000000000000000000000000000000000000000000000000000000000000858201528483015282516151228482614710565b600181527f4d000000000000000000000000000000000000000000000000000000000000008582015283830152825161515b8482614710565b600181527f420000000000000000000000000000000000000000000000000000000000000085820152606083015282516151958482614710565b600181527f54000000000000000000000000000000000000000000000000000000000000008582015260808301525f905f945b6103e882101561526f578451946151df8187614710565b600786527f2623383830353b000000000000000000000000000000000000000000000000008287015251945f5b6007811061525c575050600160fd1b602786015250600884526152439061523d90615238602887614710565b6154e9565b91615994565b916005851015614c06576148219460051b015192614fb5565b818101830151878201840152820161520c565b9490915060016103e86064600a85040693049101946151c8565b50615292614f3f565b61482160086020604051846152b082965180928580860191016146ca565b81017f203939392e393954000000000000000000000000000000000000000000000000838201520301601719810184520182614710565b600a0a9081156145e25704615030565b5050604051615307604082614710565b60018152600360fc1b602082015290565b6201518091030480615382575061532d614f7a565b614821600660206040518461534b82965180928580860191016146ca565b81017f2031204461790000000000000000000000000000000000000000000000000000838201520301601919810184520182614710565b61270f81116154595760018103615415576148216153d76040516153a7604082614710565b600481527f20446179000000000000000000000000000000000000000000000000000000006020820152926154e9565b602060405193826153f186945180928580880191016146ca565b8301615405825180938580850191016146ca565b010103601f198101835282614710565b6148216153d7604051615429604082614710565b600581527f20446179730000000000000000000000000000000000000000000000000000006020820152926154e9565b50615462614f3f565b614821600a60206040518461548082965180928580860191016146ca565b81017f2039393939204461797300000000000000000000000000000000000000000000838201520301601519810184520182614710565b906154c182614777565b6154ce6040519182614710565b82815280926154df601f1991614777565b0190602036910137565b805f917a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000821015615620575b806d04ee2d6d415b85acef8100000000600a921015615605575b662386f26fc100008110156155f1575b6305f5e1008110156155e0575b6127108110156155d1575b60648110156155c3575b10156155b8575b600a6021615573600185016154b7565b938401015b5f1901917f30313233343536373839616263646566000000000000000000000000000000008282061a83530480156155b357600a9091615578565b505090565b600190910190615563565b60646002910493019261555c565b61271060049104930192615552565b6305f5e10060089104930192615547565b662386f26fc100006010910493019261553a565b6d04ee2d6d415b85acef81000000006020910493019261552a565b50604091507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008104615510565b9081511561579d576040519161565f606084614710565b604083527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208401527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040840152805160028101809111614bf257600390047f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168103614bf2576156f59060021b6154b7565b90602082019080815182019560208701908151925f83525b88811061574f575050600393949596505251068060011461573d57600214615733575090565b603d905f19015390565b50603d90815f19820153600119015390565b600360049199969901986001603f8b5182828260121c16870101518453828282600c1c16870101518385015382828260061c168701015160028501531684010151600382015301949761570d565b90506040516157ad602082614710565b5f815290565b90815181519081811493846157ca575b5050505090565b602092939450820120920120145f8080806157c3565b908151811015614c06570160200190565b8051905f5b82811061580557505050600190565b7fff0000000000000000000000000000000000000000000000000000000000000061583082846157e0565b5116600160fd1b811490600360fc1b8110158061596a575b7f4100000000000000000000000000000000000000000000000000000000000000821015908161593f575b7f61000000000000000000000000000000000000000000000000000000000000008310159283615914575b84156158ea575b5083156158e2575b5082156158da575b5081156158d2575b50156158cb576001016157f6565b5050505f90565b90505f6158bd565b91505f6158b5565b92505f6158ad565b7f2d000000000000000000000000000000000000000000000000000000000000001493505f6158a5565b7f7a00000000000000000000000000000000000000000000000000000000000000811115935061589e565b7f5a000000000000000000000000000000000000000000000000000000000000008311159150615873565b507f3900000000000000000000000000000000000000000000000000000000000000811115615848565b806159a857506040516157ad602082614710565b600a811015615a0e576159ba906154e9565b614821602260405180937f2e3000000000000000000000000000000000000000000000000000000000000060208301526159fd81518092602086860191016146ca565b81010301601f198101835282614710565b615a17906154e9565b614821602160405180937f2e0000000000000000000000000000000000000000000000000000000000000060208301526159fd81518092602086860191016146ca565b60405190615a69604083614710565b601082527f68736c283233302c3231252c31312529000000000000000000000000000000006020830152565b8015615cc957615aa3615a5a565b9061271003906127108211614bf257602e6061916050615ac5614821956154e9565b60576040519788947f3c672066696c6c3d226e6f6e65223e000000000000000000000000000000000060208701527f3c636972636c652063783d22313636222063793d2235302220723d2232322220602f8701527f7374726f6b653d22000000000000000000000000000000000000000000000000604f870152615b52815180926020868a0191016146ca565b85017f22207374726f6b652d77696474683d223130222f3e0000000000000000000000838201527f3c636972636c652063783d22313636222063793d2235302220706174684c656e606c8201527f6774683d2231303030302220723d22323222207374726f6b653d220000000000608c820152615bd982518093602060a7850191016146ca565b01017f22207374726f6b652d6461736861727261793d22313030303022207374726f6b838201527f652d646173686f66667365743d220000000000000000000000000000000000006070820152615c3a825180936020607e850191016146ca565b01017f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d838201527f77696474683d223522207472616e73666f726d3d22726f74617465282d393029604e8201527f22207472616e73666f726d2d6f726967696e3d22313636203530222f3e000000606e820152631e17b39f60e11b608b82015203016041810184520182614710565b50506040516157ad602082614710565b600d6150209193929360206040519582615cfc88945180928580880191016146ca565b830164010714051160dd1b8382015267029b0b13634b2b9160c51b6025820152615d2f8251809385602d850191016146ca565b01010301601f198101845283614710565b60056150209193929360206040519582615d6388945180928580880191016146ca565b830164010714051160dd1b83820152615d2f82518093856025850191016146ca565b6004811015614ea85780615dcf5750604051615da2604082614710565b600881527f50726f6772657373000000000000000000000000000000000000000000000000602082015290565b60018103615e135750604051615de6604082614710565b600681527f5374617475730000000000000000000000000000000000000000000000000000602082015290565b600203615e5557604051615e28604082614710565b600681527f416d6f756e740000000000000000000000000000000000000000000000000000602082015290565b604051615e63604082614710565b600881527f4475726174696f6e000000000000000000000000000000000000000000000000602082015290565b5f90805180156158cb5790600d915f925f925b828410615eb65750505050600d02900390565b90919294603b60f81b7fff00000000000000000000000000000000000000000000000000000000000000615eea88856157e0565b511614615f00575b820194600101929190615ea3565b859450615ef2565b5f90805180156158cb57906010915f925f925b828410615f2e575050505060041b900390565b90919294603b60f81b7fff00000000000000000000000000000000000000000000000000000000000000615f6288856157e0565b511614615f78575b820194600101929190615f1b565b859450615f6a56fea164736f6c634300081a000a"; @@ -210,27 +210,22 @@ contract Precompiles { require(address(batchLockup) != address(0), "Lockup Precompiles: deployment failed for BatchLockup contract"); } - /// @notice Deploys {SablierMerkleLockupFactory} from precompiled bytecode. - function deployMerkleLockupFactory() public returns (ISablierMerkleLockupFactory factory) { - bytes memory creationBytecode = BYTECODE_MERKLE_LOCKUP_FACTORY; + /// @notice Deploys {SablierMerkleFactory} from precompiled bytecode. + function deployMerkleFactory() public returns (ISablierMerkleFactory factory) { + bytes memory creationBytecode = BYTECODE_MERKLE_FACTORY; assembly { factory := create(0, add(creationBytecode, 0x20), mload(creationBytecode)) } - require( - address(factory) != address(0), "Lockup Precompiles: deployment failed for MerkleLockupFactory contract" - ); + require(address(factory) != address(0), "Lockup Precompiles: deployment failed for MerkleFactory contract"); } /// @notice Deploys all Periphery contracts in the following order: /// /// 1. {SablierBatchLockup} - /// 2. {SablierMerkleLockupFactory} - function deployPeriphery() - public - returns (ISablierBatchLockup batchLockup, ISablierMerkleLockupFactory merkleLockupFactory) - { + /// 2. {SablierMerkleFactory} + function deployPeriphery() public returns (ISablierBatchLockup batchLockup, ISablierMerkleFactory merkleFactory) { batchLockup = deployBatchLockup(); - merkleLockupFactory = deployMerkleLockupFactory(); + merkleFactory = deployMerkleFactory(); } /// @notice Deploys the entire Lockup Protocol from precompiled bytecode. @@ -240,7 +235,7 @@ contract Precompiles { /// 3. {SablierLockupLinear} /// 4. {SablierLockupTranched} /// 5. {SablierBatchLockup} - /// 6. {SablierMerkleLockupFactory} + /// 6. {SablierMerkleFactory} function deployProtocol(address initialAdmin) public returns ( @@ -249,13 +244,13 @@ contract Precompiles { ISablierLockupTranched lockupTranched, ISablierNFTDescriptor nftDescriptor, ISablierBatchLockup batchLockup, - ISablierMerkleLockupFactory merkleLockupFactory + ISablierMerkleFactory merkleFactory ) { // Deploy Core. (lockupDynamic, lockupLinear, lockupTranched, nftDescriptor) = deployCore(initialAdmin); // Deploy Periphery. - (batchLockup, merkleLockupFactory) = deployPeriphery(); + (batchLockup, merkleFactory) = deployPeriphery(); } } diff --git a/script/DeployDeterministicProtocol.s.sol b/script/DeployDeterministicProtocol.s.sol index 2604749ed..6cd5dc10e 100644 --- a/script/DeployDeterministicProtocol.s.sol +++ b/script/DeployDeterministicProtocol.s.sol @@ -5,7 +5,7 @@ import { SablierLockupDynamic } from "../src/core/SablierLockupDynamic.sol"; import { SablierLockupLinear } from "../src/core/SablierLockupLinear.sol"; import { SablierLockupTranched } from "../src/core/SablierLockupTranched.sol"; import { SablierNFTDescriptor } from "../src/core/SablierNFTDescriptor.sol"; -import { SablierMerkleLockupFactory } from "../src/periphery/SablierMerkleLockupFactory.sol"; +import { SablierMerkleFactory } from "../src/periphery/SablierMerkleFactory.sol"; import { SablierBatchLockup } from "../src/periphery/SablierBatchLockup.sol"; import { BaseScript } from "./Base.s.sol"; @@ -23,7 +23,7 @@ contract DeployDeterministicProtocol is BaseScript { SablierLockupTranched lockupTranched, SablierNFTDescriptor nftDescriptor, SablierBatchLockup batchLockup, - SablierMerkleLockupFactory merkleLockupFactory + SablierMerkleFactory merkleFactory ) { bytes32 salt = constructCreate2Salt(); @@ -38,6 +38,6 @@ contract DeployDeterministicProtocol is BaseScript { // Deploy Periphery. batchLockup = new SablierBatchLockup{ salt: salt }(); - merkleLockupFactory = new SablierMerkleLockupFactory{ salt: salt }(); + merkleFactory = new SablierMerkleFactory{ salt: salt }(); } } diff --git a/script/DeployProtocol.s.sol b/script/DeployProtocol.s.sol index 18b914a87..dacb0aedd 100644 --- a/script/DeployProtocol.s.sol +++ b/script/DeployProtocol.s.sol @@ -5,7 +5,7 @@ import { SablierLockupDynamic } from "../src/core/SablierLockupDynamic.sol"; import { SablierLockupLinear } from "../src/core/SablierLockupLinear.sol"; import { SablierLockupTranched } from "../src/core/SablierLockupTranched.sol"; import { SablierNFTDescriptor } from "../src/core/SablierNFTDescriptor.sol"; -import { SablierMerkleLockupFactory } from "../src/periphery/SablierMerkleLockupFactory.sol"; +import { SablierMerkleFactory } from "../src/periphery/SablierMerkleFactory.sol"; import { SablierBatchLockup } from "../src/periphery/SablierBatchLockup.sol"; import { BaseScript } from "./Base.s.sol"; @@ -23,7 +23,7 @@ contract DeployProtocol is BaseScript { SablierLockupTranched lockupTranched, SablierNFTDescriptor nftDescriptor, SablierBatchLockup batchLockup, - SablierMerkleLockupFactory merkleLockupFactory + SablierMerkleFactory merkleFactory ) { // Deploy Core. @@ -34,6 +34,6 @@ contract DeployProtocol is BaseScript { // Deploy Periphery. batchLockup = new SablierBatchLockup(); - merkleLockupFactory = new SablierMerkleLockupFactory(); + merkleFactory = new SablierMerkleFactory(); } } diff --git a/script/periphery/CreateMerkleLL.s.sol b/script/periphery/CreateMerkleLL.s.sol index 46da619be..972649b65 100644 --- a/script/periphery/CreateMerkleLL.s.sol +++ b/script/periphery/CreateMerkleLL.s.sol @@ -6,8 +6,8 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierLockupLinear } from "../../src/core/interfaces/ISablierLockupLinear.sol"; import { LockupLinear } from "../../src/core/types/DataTypes.sol"; import { ISablierMerkleLL } from "../../src/periphery/interfaces/ISablierMerkleLL.sol"; -import { ISablierMerkleLockupFactory } from "../../src/periphery/interfaces/ISablierMerkleLockupFactory.sol"; -import { MerkleLockup } from "../../src/periphery/types/DataTypes.sol"; +import { ISablierMerkleFactory } from "../../src/periphery/interfaces/ISablierMerkleFactory.sol"; +import { MerkleBase } from "../../src/periphery/types/DataTypes.sol"; import { BaseScript } from "../Base.s.sol"; @@ -15,20 +15,19 @@ contract CreateMerkleLL is BaseScript { /// @dev Deploy via Forge. function run() public virtual broadcast returns (ISablierMerkleLL merkleLL) { // Prepare the constructor parameters. - ISablierMerkleLockupFactory merkleLockupFactory = - ISablierMerkleLockupFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc); + ISablierMerkleFactory merkleFactory = ISablierMerkleFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc); - MerkleLockup.ConstructorParams memory baseParams; + MerkleBase.ConstructorParams memory baseParams; baseParams.asset = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); - baseParams.cancelable = true; baseParams.expiration = uint40(block.timestamp + 30 days); baseParams.initialAdmin = 0x79Fb3e81aAc012c08501f41296CCC145a1E15844; baseParams.ipfsCID = "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"; baseParams.merkleRoot = 0x0000000000000000000000000000000000000000000000000000000000000000; baseParams.name = "The Boys LL"; - baseParams.transferable = true; ISablierLockupLinear lockupLinear = ISablierLockupLinear(0x3962f6585946823440d274aD7C719B02b49DE51E); + bool cancelable = true; + bool transferable = true; LockupLinear.Durations memory streamDurations; streamDurations.cliff = 0; streamDurations.total = 3600; @@ -36,8 +35,8 @@ contract CreateMerkleLL is BaseScript { uint256 recipientCount = 100; // Deploy MerkleLL contract. - merkleLL = merkleLockupFactory.createMerkleLL( - baseParams, lockupLinear, streamDurations, campaignTotalAmount, recipientCount + merkleLL = merkleFactory.createMerkleLL( + baseParams, lockupLinear, cancelable, transferable, streamDurations, campaignTotalAmount, recipientCount ); } } diff --git a/script/periphery/CreateMerkleLT.s.sol b/script/periphery/CreateMerkleLT.s.sol index f19bb5abe..eaa8a1aa6 100644 --- a/script/periphery/CreateMerkleLT.s.sol +++ b/script/periphery/CreateMerkleLT.s.sol @@ -5,9 +5,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { UD2x18 } from "@prb/math/src/UD2x18.sol"; import { ISablierLockupTranched } from "../../src/core/interfaces/ISablierLockupTranched.sol"; -import { ISablierMerkleLockupFactory } from "../../src/periphery/interfaces/ISablierMerkleLockupFactory.sol"; +import { ISablierMerkleFactory } from "../../src/periphery/interfaces/ISablierMerkleFactory.sol"; import { ISablierMerkleLT } from "../../src/periphery/interfaces/ISablierMerkleLT.sol"; -import { MerkleLockup, MerkleLT } from "../../src/periphery/types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "../../src/periphery/types/DataTypes.sol"; import { BaseScript } from "../Base.s.sol"; @@ -15,20 +15,19 @@ contract CreateMerkleLT is BaseScript { /// @dev Deploy via Forge. function run() public virtual broadcast returns (ISablierMerkleLT merkleLT) { // Prepare the constructor parameters. - ISablierMerkleLockupFactory merkleLockupFactory = - ISablierMerkleLockupFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc); + ISablierMerkleFactory merkleFactory = ISablierMerkleFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc); - MerkleLockup.ConstructorParams memory baseParams; + MerkleBase.ConstructorParams memory baseParams; baseParams.asset = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); - baseParams.cancelable = true; baseParams.expiration = uint40(block.timestamp + 30 days); baseParams.initialAdmin = 0x79Fb3e81aAc012c08501f41296CCC145a1E15844; baseParams.ipfsCID = "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"; baseParams.merkleRoot = 0x0000000000000000000000000000000000000000000000000000000000000000; baseParams.name = "The Boys LT"; - baseParams.transferable = true; ISablierLockupTranched lockupTranched = ISablierLockupTranched(0xf86B359035208e4529686A1825F2D5BeE38c28A8); + bool cancelable = true; + bool transferable = true; MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages = new MerkleLT.TrancheWithPercentage[](2); tranchesWithPercentages[0] = MerkleLT.TrancheWithPercentage({ unlockPercentage: UD2x18.wrap(50), duration: 3600 }); @@ -38,8 +37,14 @@ contract CreateMerkleLT is BaseScript { uint256 recipientCount = 100; // Deploy MerkleLT contract. - merkleLT = merkleLockupFactory.createMerkleLT( - baseParams, lockupTranched, tranchesWithPercentages, campaignTotalAmount, recipientCount + merkleLT = merkleFactory.createMerkleLT( + baseParams, + lockupTranched, + cancelable, + transferable, + tranchesWithPercentages, + campaignTotalAmount, + recipientCount ); } } diff --git a/script/periphery/DeployDeterministicPeriphery.s.sol b/script/periphery/DeployDeterministicPeriphery.s.sol index 8cde8dc60..40c8bf2ac 100644 --- a/script/periphery/DeployDeterministicPeriphery.s.sol +++ b/script/periphery/DeployDeterministicPeriphery.s.sol @@ -2,14 +2,14 @@ pragma solidity >=0.8.22 <0.9.0; import { SablierBatchLockup } from "../../src/periphery/SablierBatchLockup.sol"; -import { SablierMerkleLockupFactory } from "../../src/periphery/SablierMerkleLockupFactory.sol"; +import { SablierMerkleFactory } from "../../src/periphery/SablierMerkleFactory.sol"; import { BaseScript } from "../Base.s.sol"; /// @notice Deploys all Periphery contracts at deterministic addresses across chains, in the following order: /// /// 1. {SablierBatchLockup} -/// 2. {SablierMerkleLockupFactory} +/// 2. {SablierMerkleFactory} /// /// @dev Reverts if any contract has already been deployed. contract DeployDeterministicPeriphery is BaseScript { @@ -18,10 +18,10 @@ contract DeployDeterministicPeriphery is BaseScript { public virtual broadcast - returns (SablierBatchLockup batchLockup, SablierMerkleLockupFactory merkleLockupFactory) + returns (SablierBatchLockup batchLockup, SablierMerkleFactory merkleFactory) { bytes32 salt = constructCreate2Salt(); batchLockup = new SablierBatchLockup{ salt: salt }(); - merkleLockupFactory = new SablierMerkleLockupFactory{ salt: salt }(); + merkleFactory = new SablierMerkleFactory{ salt: salt }(); } } diff --git a/script/periphery/DeployMerkleLockupFactory.s.sol b/script/periphery/DeployMerkleLockupFactory.s.sol index 4b84e4c62..c44cea888 100644 --- a/script/periphery/DeployMerkleLockupFactory.s.sol +++ b/script/periphery/DeployMerkleLockupFactory.s.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.22 <0.9.0; -import { SablierMerkleLockupFactory } from "../../src/periphery/SablierMerkleLockupFactory.sol"; +import { SablierMerkleFactory } from "../../src/periphery/SablierMerkleFactory.sol"; import { BaseScript } from "../Base.s.sol"; -contract DeployMerkleLockupFactory is BaseScript { +contract DeployMerkleFactory is BaseScript { /// @dev Deploy via Forge. - function run() public virtual broadcast returns (SablierMerkleLockupFactory merkleLockupFactory) { - merkleLockupFactory = new SablierMerkleLockupFactory(); + function run() public virtual broadcast returns (SablierMerkleFactory merkleFactory) { + merkleFactory = new SablierMerkleFactory(); } } diff --git a/script/periphery/DeployPeriphery.s.sol b/script/periphery/DeployPeriphery.s.sol index 519272717..9e8d554d2 100644 --- a/script/periphery/DeployPeriphery.s.sol +++ b/script/periphery/DeployPeriphery.s.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.22 <0.9.0; -import { SablierMerkleLockupFactory } from "../../src/periphery/SablierMerkleLockupFactory.sol"; +import { SablierMerkleFactory } from "../../src/periphery/SablierMerkleFactory.sol"; import { SablierBatchLockup } from "../../src/periphery/SablierBatchLockup.sol"; import { BaseScript } from "../Base.s.sol"; @@ -9,16 +9,16 @@ import { BaseScript } from "../Base.s.sol"; /// @notice Deploys all Periphery contract in the following order: /// /// 1. {SablierBatchLockup} -/// 2. {SablierMerkleLockupFactory} +/// 2. {SablierMerkleFactory} contract DeployPeriphery is BaseScript { /// @dev Deploy via Forge. function run() public virtual broadcast - returns (SablierBatchLockup batchLockup, SablierMerkleLockupFactory merkleLockupFactory) + returns (SablierBatchLockup batchLockup, SablierMerkleFactory merkleFactory) { batchLockup = new SablierBatchLockup(); - merkleLockupFactory = new SablierMerkleLockupFactory(); + merkleFactory = new SablierMerkleFactory(); } } diff --git a/shell/deploy-multi-chain.sh b/shell/deploy-multi-chain.sh index cf2bc8134..67d1bc6b6 100755 --- a/shell/deploy-multi-chain.sh +++ b/shell/deploy-multi-chain.sh @@ -360,7 +360,7 @@ for chain in "${provided_chains[@]}"; do lockupDynamic_address=$(echo "${output}" | awk '/lockupDynamic: contract/{print $NF}') lockupLinear_address=$(echo "${output}" | awk '/lockupLinear: contract/{print $NF}') lockupTranched_address=$(echo "${output}" | awk '/lockupTranched: contract/{print $NF}') - merkleLockupFactory_address=$(echo "${output}" | awk '/merkleLockupFactory: contract/{print $NF}') + merkleFactory_address=$(echo "${output}" | awk '/merkleFactory: contract/{print $NF}') nftDescriptor_address=$(echo "${output}" | awk '/nftDescriptor: contract/{print $NF}') # Save to the chain file @@ -372,7 +372,7 @@ for chain in "${provided_chains[@]}"; do echo "SablierNFTDescriptor = ${nftDescriptor_address}" echo "Periphery Contracts" echo "SablierBatchLockup = ${batchLockup_address}" - echo "SablierMerkleLockupFactory = ${merkleLockupFactory_address}" + echo "SablierMerkleFactory = ${merkleFactory_address}" } >> "$chain_file" echo -e "${SC}${TICK} Deployed on ${chain}. You can find the addresses in ${chain_file}${NC}" diff --git a/shell/prepare-artifacts.sh b/shell/prepare-artifacts.sh index 6df15e95c..a3dc7b3bd 100755 --- a/shell/prepare-artifacts.sh +++ b/shell/prepare-artifacts.sh @@ -52,14 +52,16 @@ cp out-optimized/Errors.sol/Errors.json $core_libraries periphery=./artifacts/periphery cp out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json $periphery +cp out-optimized/SablierMerkleFactory.sol/SablierMerkleFactory.json $periphery +cp out-optimized/SablierMerkleInstant.sol/SablierMerkleInstant.json $periphery cp out-optimized/SablierMerkleLL.sol/SablierMerkleLL.json $periphery -cp out-optimized/SablierMerkleLockupFactory.sol/SablierMerkleLockupFactory.json $periphery cp out-optimized/SablierMerkleLT.sol/SablierMerkleLT.json $periphery periphery_interfaces=./artifacts/periphery/interfaces cp out-optimized/ISablierBatchLockup.sol/ISablierBatchLockup.json $periphery_interfaces +cp out-optimized/ISablierMerkleFactory.sol/ISablierMerkleFactory.json $periphery_interfaces +cp out-optimized/ISablierMerkleInstant.sol/ISablierMerkleInstant.json $periphery_interfaces cp out-optimized/ISablierMerkleLL.sol/ISablierMerkleLL.json $periphery_interfaces -cp out-optimized/ISablierMerkleLockupFactory.sol/ISablierMerkleLockupFactory.json $periphery_interfaces cp out-optimized/ISablierMerkleLT.sol/ISablierMerkleLT.json $periphery_interfaces periphery_libraries=./artifacts/periphery/libraries diff --git a/shell/update-precompiles.sh b/shell/update-precompiles.sh index d214f114e..fc8a858e7 100755 --- a/shell/update-precompiles.sh +++ b/shell/update-precompiles.sh @@ -16,7 +16,7 @@ batch_lockup=$(cat out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json lockup_dynamic=$(cat out-optimized/SablierLockupDynamic.sol/SablierLockupDynamic.json | jq -r '.bytecode.object' | cut -c 3-) lockup_linear=$(cat out-optimized/SablierLockupLinear.sol/SablierLockupLinear.json | jq -r '.bytecode.object' | cut -c 3-) lockup_tranched=$(cat out-optimized/SablierLockupTranched.sol/SablierLockupTranched.json | jq -r '.bytecode.object' | cut -c 3-) -merkle_lockup_factory=$(cat out-optimized/SablierMerkleLockupFactory.sol/SablierMerkleLockupFactory.json | jq -r '.bytecode.object' | cut -c 3-) +merkle_factory=$(cat out-optimized/SablierMerkleFactory.sol/SablierMerkleFactory.json | jq -r '.bytecode.object' | cut -c 3-) nft_descriptor=$(cat out-optimized/SablierNFTDescriptor.sol/SablierNFTDescriptor.json | jq -r '.bytecode.object' | cut -c 3-) precompiles_path="precompiles/Precompiles.sol" @@ -30,7 +30,7 @@ sd "(BYTECODE_BATCH_LOCKUP =)[^;]+;" "\$1 hex\"$batch_lockup\";" $precompiles_pa sd "(BYTECODE_LOCKUP_DYNAMIC =)[^;]+;" "\$1 hex\"$lockup_dynamic\";" $precompiles_path sd "(BYTECODE_LOCKUP_LINEAR =)[^;]+;" "\$1 hex\"$lockup_linear\";" $precompiles_path sd "(BYTECODE_LOCKUP_TRANCHED =)[^;]+;" "\$1 hex\"$lockup_tranched\";" $precompiles_path -sd "(BYTECODE_MERKLE_LOCKUP_FACTORY =)[^;]+;" "\$1 hex\"$merkle_lockup_factory\";" $precompiles_path +sd "(BYTECODE_MERKLE_FACTORY =)[^;]+;" "\$1 hex\"$merkle_factory\";" $precompiles_path sd "(BYTECODE_NFT_DESCRIPTOR =)[^;]+;" "\$1 hex\"$nft_descriptor\";" $precompiles_path # Reformat the code with Forge diff --git a/src/periphery/SablierMerkleLockupFactory.sol b/src/periphery/SablierMerkleFactory.sol similarity index 70% rename from src/periphery/SablierMerkleLockupFactory.sol rename to src/periphery/SablierMerkleFactory.sol index 80d83f50c..3cb2260fb 100644 --- a/src/periphery/SablierMerkleLockupFactory.sol +++ b/src/periphery/SablierMerkleFactory.sol @@ -7,23 +7,23 @@ import { ISablierLockupLinear } from "../core/interfaces/ISablierLockupLinear.so import { ISablierLockupTranched } from "../core/interfaces/ISablierLockupTranched.sol"; import { LockupLinear } from "../core/types/DataTypes.sol"; +import { ISablierMerkleFactory } from "./interfaces/ISablierMerkleFactory.sol"; import { ISablierMerkleInstant } from "./interfaces/ISablierMerkleInstant.sol"; import { ISablierMerkleLL } from "./interfaces/ISablierMerkleLL.sol"; -import { ISablierMerkleLockupFactory } from "./interfaces/ISablierMerkleLockupFactory.sol"; import { ISablierMerkleLT } from "./interfaces/ISablierMerkleLT.sol"; +import { SablierMerkleInstant } from "./SablierMerkleInstant.sol"; import { SablierMerkleLL } from "./SablierMerkleLL.sol"; import { SablierMerkleLT } from "./SablierMerkleLT.sol"; -import { SablierMerkleInstant } from "./SablierMerkleInstant.sol"; -import { MerkleLockup, MerkleLT } from "./types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "./types/DataTypes.sol"; -/// @title SablierMerkleLockupFactory -/// @notice See the documentation in {ISablierMerkleLockupFactory}. -contract SablierMerkleLockupFactory is ISablierMerkleLockupFactory { +/// @title SablierMerkleFactory +/// @notice See the documentation in {ISablierMerkleFactory}. +contract SablierMerkleFactory is ISablierMerkleFactory { /*////////////////////////////////////////////////////////////////////////// USER-FACING CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ - /// @inheritdoc ISablierMerkleLockupFactory + /// @inheritdoc ISablierMerkleFactory function isPercentagesSum100(MerkleLT.TrancheWithPercentage[] calldata tranches) external pure @@ -41,9 +41,9 @@ contract SablierMerkleLockupFactory is ISablierMerkleLockupFactory { USER-FACING NON-CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ - /// @notice inheritdoc ISablierMerkleLockupFactory + /// @notice inheritdoc ISablierMerkleFactory function createMerkleInstant( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, uint256 aggregateAmount, uint256 recipientCount ) @@ -63,17 +63,19 @@ contract SablierMerkleLockupFactory is ISablierMerkleLockupFactory { ) ); - // Deploy the MerkleLockup contract with CREATE2. + // Deploy the MerkleInstant contract with CREATE2. merkleInstant = new SablierMerkleInstant{ salt: salt }(baseParams); - // Log the creation of the MerkleLockup contract, including some metadata that is not stored on-chain. + // Log the creation of the MerkleInstant contract, including some metadata that is not stored on-chain. emit CreateMerkleInstant(merkleInstant, baseParams, aggregateAmount, recipientCount); } - /// @notice inheritdoc ISablierMerkleLockupFactory + /// @notice inheritdoc ISablierMerkleFactory function createMerkleLL( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, ISablierLockupLinear lockupLinear, + bool cancelable, + bool transferable, LockupLinear.Durations memory streamDurations, uint256 aggregateAmount, uint256 recipientCount @@ -86,29 +88,41 @@ contract SablierMerkleLockupFactory is ISablierMerkleLockupFactory { abi.encodePacked( msg.sender, baseParams.asset, - baseParams.cancelable, baseParams.expiration, baseParams.initialAdmin, abi.encode(baseParams.ipfsCID), baseParams.merkleRoot, bytes32(abi.encodePacked(baseParams.name)), - baseParams.transferable, lockupLinear, + cancelable, + transferable, abi.encode(streamDurations) ) ); - // Deploy the MerkleLockup contract with CREATE2. - merkleLL = new SablierMerkleLL{ salt: salt }(baseParams, lockupLinear, streamDurations); + // Deploy the MerkleLL contract with CREATE2. + merkleLL = + new SablierMerkleLL{ salt: salt }(baseParams, lockupLinear, cancelable, transferable, streamDurations); - // Log the creation of the MerkleLockup contract, including some metadata that is not stored on-chain. - emit CreateMerkleLL(merkleLL, baseParams, lockupLinear, streamDurations, aggregateAmount, recipientCount); + // Log the creation of the MerkleLL contract, including some metadata that is not stored on-chain. + emit CreateMerkleLL( + merkleLL, + baseParams, + lockupLinear, + cancelable, + transferable, + streamDurations, + aggregateAmount, + recipientCount + ); } - /// @notice inheritdoc ISablierMerkleLockupFactory + /// @notice inheritdoc ISablierMerkleFactory function createMerkleLT( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, ISablierLockupTranched lockupTranched, + bool cancelable, + bool transferable, MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages, uint256 aggregateAmount, uint256 recipientCount @@ -135,26 +149,30 @@ contract SablierMerkleLockupFactory is ISablierMerkleLockupFactory { abi.encodePacked( msg.sender, baseParams.asset, - baseParams.cancelable, baseParams.expiration, baseParams.initialAdmin, abi.encode(baseParams.ipfsCID), baseParams.merkleRoot, bytes32(abi.encodePacked(baseParams.name)), - baseParams.transferable, lockupTranched, + cancelable, + transferable, abi.encode(tranchesWithPercentages) ) ); - // Deploy the MerkleLockup contract with CREATE2. - merkleLT = new SablierMerkleLT{ salt: salt }(baseParams, lockupTranched, tranchesWithPercentages); + // Deploy the MerkleLT contract with CREATE2. + merkleLT = new SablierMerkleLT{ salt: salt }( + baseParams, lockupTranched, cancelable, transferable, tranchesWithPercentages + ); - // Log the creation of the MerkleLockup contract, including some metadata that is not stored on-chain. + // Log the creation of the MerkleLT contract, including some metadata that is not stored on-chain. emit CreateMerkleLT( merkleLT, baseParams, lockupTranched, + cancelable, + transferable, tranchesWithPercentages, totalDuration, aggregateAmount, diff --git a/src/periphery/SablierMerkleInstant.sol b/src/periphery/SablierMerkleInstant.sol index b66779353..62c3450d1 100644 --- a/src/periphery/SablierMerkleInstant.sol +++ b/src/periphery/SablierMerkleInstant.sol @@ -5,15 +5,15 @@ import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { SablierMerkleLockup } from "./abstracts/SablierMerkleLockup.sol"; +import { SablierMerkleBase } from "./abstracts/SablierMerkleBase.sol"; import { ISablierMerkleInstant } from "./interfaces/ISablierMerkleInstant.sol"; -import { MerkleLockup } from "./types/DataTypes.sol"; +import { MerkleBase } from "./types/DataTypes.sol"; /// @title SablierMerkleInstant /// @notice See the documentation in {ISablierMerkleInstant}. contract SablierMerkleInstant is ISablierMerkleInstant, // 2 inherited components - SablierMerkleLockup // 4 inherited components + SablierMerkleBase // 4 inherited components { using BitMaps for BitMaps.BitMap; using SafeERC20 for IERC20; @@ -23,7 +23,7 @@ contract SablierMerkleInstant is //////////////////////////////////////////////////////////////////////////*/ /// @dev Constructs the contract by initializing the immutable state variables. - constructor(MerkleLockup.ConstructorParams memory baseParams) SablierMerkleLockup(baseParams) { } + constructor(MerkleBase.ConstructorParams memory baseParams) SablierMerkleBase(baseParams) { } /*////////////////////////////////////////////////////////////////////////// USER-FACING NON-CONSTANT FUNCTIONS diff --git a/src/periphery/SablierMerkleLL.sol b/src/periphery/SablierMerkleLL.sol index 9971f32c3..e56967d37 100644 --- a/src/periphery/SablierMerkleLL.sol +++ b/src/periphery/SablierMerkleLL.sol @@ -9,15 +9,15 @@ import { ud } from "@prb/math/src/UD60x18.sol"; import { ISablierLockupLinear } from "../core/interfaces/ISablierLockupLinear.sol"; import { Broker, LockupLinear } from "../core/types/DataTypes.sol"; -import { SablierMerkleLockup } from "./abstracts/SablierMerkleLockup.sol"; +import { SablierMerkleBase } from "./abstracts/SablierMerkleBase.sol"; import { ISablierMerkleLL } from "./interfaces/ISablierMerkleLL.sol"; -import { MerkleLockup } from "./types/DataTypes.sol"; +import { MerkleBase } from "./types/DataTypes.sol"; /// @title SablierMerkleLL /// @notice See the documentation in {ISablierMerkleLL}. contract SablierMerkleLL is ISablierMerkleLL, // 2 inherited components - SablierMerkleLockup // 4 inherited components + SablierMerkleBase // 4 inherited components { using BitMaps for BitMaps.BitMap; using SafeERC20 for IERC20; @@ -45,18 +45,20 @@ contract SablierMerkleLL is /// @dev Constructs the contract by initializing the immutable state variables, and max approving the Lockup /// contract. constructor( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, ISablierLockupLinear lockupLinear, + bool cancelable, + bool transferable, LockupLinear.Durations memory streamDurations_ ) - SablierMerkleLockup(baseParams) + SablierMerkleBase(baseParams) { - CANCELABLE = baseParams.cancelable; + CANCELABLE = cancelable; LOCKUP_LINEAR = lockupLinear; - TRANSFERABLE = baseParams.transferable; + TRANSFERABLE = transferable; streamDurations = streamDurations_; - // Max approve the Lockup contract to spend funds from the MerkleLockup contract. + // Max approve the Lockup contract to spend funds from the MerkleLL contract. ASSET.forceApprove(address(LOCKUP_LINEAR), type(uint256).max); } diff --git a/src/periphery/SablierMerkleLT.sol b/src/periphery/SablierMerkleLT.sol index 00e2b1647..a1f41c59a 100644 --- a/src/periphery/SablierMerkleLT.sol +++ b/src/periphery/SablierMerkleLT.sol @@ -10,16 +10,16 @@ import { UD60x18, ud60x18, ZERO } from "@prb/math/src/UD60x18.sol"; import { ISablierLockupTranched } from "../core/interfaces/ISablierLockupTranched.sol"; import { Broker, LockupTranched } from "../core/types/DataTypes.sol"; -import { SablierMerkleLockup } from "./abstracts/SablierMerkleLockup.sol"; +import { SablierMerkleBase } from "./abstracts/SablierMerkleBase.sol"; import { ISablierMerkleLT } from "./interfaces/ISablierMerkleLT.sol"; import { Errors } from "./libraries/Errors.sol"; -import { MerkleLockup, MerkleLT } from "./types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "./types/DataTypes.sol"; /// @title SablierMerkleLT /// @notice See the documentation in {ISablierMerkleLT}. contract SablierMerkleLT is ISablierMerkleLT, // 2 inherited components - SablierMerkleLockup // 4 inherited components + SablierMerkleBase // 4 inherited components { using BitMaps for BitMaps.BitMap; using SafeERC20 for IERC20; @@ -50,14 +50,17 @@ contract SablierMerkleLT is /// @dev Constructs the contract by initializing the immutable state variables, and max approving the Lockup /// contract. constructor( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, ISablierLockupTranched lockupTranched, + bool cancelable, + bool transferable, MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages ) - SablierMerkleLockup(baseParams) + SablierMerkleBase(baseParams) { - CANCELABLE = baseParams.cancelable; + CANCELABLE = cancelable; LOCKUP_TRANCHED = lockupTranched; + TRANSFERABLE = transferable; uint256 count = tranchesWithPercentages.length; @@ -70,9 +73,7 @@ contract SablierMerkleLT is } TOTAL_PERCENTAGE = totalPercentage; - TRANSFERABLE = baseParams.transferable; - - // Max approve the Lockup contract to spend funds from the MerkleLockup contract. + // Max approve the Lockup contract to spend funds from the MerkleLT contract. ASSET.forceApprove(address(LOCKUP_TRANCHED), type(uint256).max); } diff --git a/src/periphery/abstracts/SablierMerkleLockup.sol b/src/periphery/abstracts/SablierMerkleBase.sol similarity index 79% rename from src/periphery/abstracts/SablierMerkleLockup.sol rename to src/periphery/abstracts/SablierMerkleBase.sol index a6200b682..fcfe60722 100644 --- a/src/periphery/abstracts/SablierMerkleLockup.sol +++ b/src/periphery/abstracts/SablierMerkleBase.sol @@ -8,14 +8,14 @@ import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; import { Adminable } from "../../core/abstracts/Adminable.sol"; -import { ISablierMerkleLockup } from "../interfaces/ISablierMerkleLockup.sol"; -import { MerkleLockup } from "../types/DataTypes.sol"; +import { ISablierMerkleBase } from "../interfaces/ISablierMerkleBase.sol"; +import { MerkleBase } from "../types/DataTypes.sol"; import { Errors } from "../libraries/Errors.sol"; -/// @title SablierMerkleLockup -/// @notice See the documentation in {ISablierMerkleLockup}. -abstract contract SablierMerkleLockup is - ISablierMerkleLockup, // 2 inherited component +/// @title SablierMerkleBase +/// @notice See the documentation in {ISablierMerkleBase}. +abstract contract SablierMerkleBase is + ISablierMerkleBase, // 2 inherited component Adminable // 1 inherited component { using BitMaps for BitMaps.BitMap; @@ -25,19 +25,19 @@ abstract contract SablierMerkleLockup is STATE VARIABLES //////////////////////////////////////////////////////////////////////////*/ - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase IERC20 public immutable override ASSET; - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase uint40 public immutable override EXPIRATION; - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase bytes32 public immutable override MERKLE_ROOT; /// @dev The name of the campaign stored as bytes32. bytes32 internal immutable NAME; - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase string public ipfsCID; /// @dev Packed booleans that record the history of claims. @@ -51,13 +51,10 @@ abstract contract SablierMerkleLockup is //////////////////////////////////////////////////////////////////////////*/ /// @dev Constructs the contract by initializing the immutable state variables. - constructor(MerkleLockup.ConstructorParams memory params) { + constructor(MerkleBase.ConstructorParams memory params) { // Check: the campaign name is not greater than 32 bytes if (bytes(params.name).length > 32) { - revert Errors.SablierMerkleLockup_CampaignNameTooLong({ - nameLength: bytes(params.name).length, - maxLength: 32 - }); + revert Errors.SablierMerkleBase_CampaignNameTooLong({ nameLength: bytes(params.name).length, maxLength: 32 }); } admin = params.initialAdmin; @@ -72,22 +69,22 @@ abstract contract SablierMerkleLockup is USER-FACING CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase function getFirstClaimTime() external view override returns (uint40) { return _firstClaimTime; } - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase function hasClaimed(uint256 index) public view override returns (bool) { return _claimedBitMap.get(index); } - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase function hasExpired() public view override returns (bool) { return EXPIRATION > 0 && EXPIRATION <= block.timestamp; } - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase function name() external view override returns (string memory) { return string(abi.encodePacked(NAME)); } @@ -96,11 +93,11 @@ abstract contract SablierMerkleLockup is USER-FACING NON-CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ - /// @inheritdoc ISablierMerkleLockup + /// @inheritdoc ISablierMerkleBase function clawback(address to, uint128 amount) external override onlyAdmin { // Check: current timestamp is over the grace period and the campaign has not expired. if (_hasGracePeriodPassed() && !hasExpired()) { - revert Errors.SablierMerkleLockup_ClawbackNotAllowed({ + revert Errors.SablierMerkleBase_ClawbackNotAllowed({ blockTimestamp: block.timestamp, expiration: EXPIRATION, firstClaimTime: _firstClaimTime @@ -132,17 +129,17 @@ abstract contract SablierMerkleLockup is function _checkClaim(uint256 index, bytes32 leaf, bytes32[] calldata merkleProof) internal { // Check: the campaign has not expired. if (hasExpired()) { - revert Errors.SablierMerkleLockup_CampaignExpired({ blockTimestamp: block.timestamp, expiration: EXPIRATION }); + revert Errors.SablierMerkleBase_CampaignExpired({ blockTimestamp: block.timestamp, expiration: EXPIRATION }); } // Check: the index has not been claimed. if (_claimedBitMap.get(index)) { - revert Errors.SablierMerkleLockup_StreamClaimed(index); + revert Errors.SablierMerkleBase_StreamClaimed(index); } // Check: the input claim is included in the Merkle tree. if (!MerkleProof.verify(merkleProof, MERKLE_ROOT, leaf)) { - revert Errors.SablierMerkleLockup_InvalidProof(); + revert Errors.SablierMerkleBase_InvalidProof(); } // Effect: set the `_firstClaimTime` if its zero. diff --git a/src/periphery/interfaces/ISablierMerkleLockup.sol b/src/periphery/interfaces/ISablierMerkleBase.sol similarity index 85% rename from src/periphery/interfaces/ISablierMerkleLockup.sol rename to src/periphery/interfaces/ISablierMerkleBase.sol index 460009ff9..157f2507c 100644 --- a/src/periphery/interfaces/ISablierMerkleLockup.sol +++ b/src/periphery/interfaces/ISablierMerkleBase.sol @@ -5,12 +5,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IAdminable } from "../../core/interfaces/IAdminable.sol"; -/// @title ISablierMerkleLockup -/// @notice A contract that lets user claim Lockup streams using Merkle proofs. A popular use case for MerkleLockup -/// is airstreams: a portmanteau of "airdrop" and "stream". This is an airdrop model where the tokens are distributed -/// over time, as opposed to all at once. -/// @dev This is the base interface for MerkleLockup. See the Sablier docs for more guidance: https://docs.sablier.com -interface ISablierMerkleLockup is IAdminable { +/// @title ISablierMerkleBase +/// @dev This is the base interface for MerkleLockups and MerkleInstant. +interface ISablierMerkleBase is IAdminable { /*////////////////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////////////////*/ @@ -30,6 +27,10 @@ interface ISablierMerkleLockup is IAdminable { /// @dev This is an immutable state variable. function EXPIRATION() external returns (uint40); + /// @notice The root of the Merkle tree used to validate the proofs of inclusion. + /// @dev This is an immutable state variable. + function MERKLE_ROOT() external returns (bytes32); + /// @notice Returns the timestamp when the first claim is made. function getFirstClaimTime() external view returns (uint40); @@ -44,10 +45,6 @@ interface ISablierMerkleLockup is IAdminable { /// @notice The content identifier for indexing the campaign on IPFS. function ipfsCID() external view returns (string memory); - /// @notice The root of the Merkle tree used to validate the proofs of inclusion. - /// @dev This is an immutable state variable. - function MERKLE_ROOT() external returns (bytes32); - /// @notice Retrieves the name of the campaign. function name() external returns (string memory); diff --git a/src/periphery/interfaces/ISablierMerkleLockupFactory.sol b/src/periphery/interfaces/ISablierMerkleFactory.sol similarity index 67% rename from src/periphery/interfaces/ISablierMerkleLockupFactory.sol rename to src/periphery/interfaces/ISablierMerkleFactory.sol index 4ccf788ff..6189322f8 100644 --- a/src/periphery/interfaces/ISablierMerkleLockupFactory.sol +++ b/src/periphery/interfaces/ISablierMerkleFactory.sol @@ -8,11 +8,16 @@ import { LockupLinear } from "../../core/types/DataTypes.sol"; import { ISablierMerkleInstant } from "./ISablierMerkleInstant.sol"; import { ISablierMerkleLL } from "./ISablierMerkleLL.sol"; import { ISablierMerkleLT } from "./ISablierMerkleLT.sol"; -import { MerkleLockup, MerkleLT } from "../types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "../types/DataTypes.sol"; -/// @title ISablierMerkleLockupFactory -/// @notice Deploys MerkleLockup campaigns with CREATE2. -interface ISablierMerkleLockupFactory { +/// @title ISablierMerkleFactory +/// @notice A contract that deploys MerkleBase and MerkleInstant campaigns. Both of these use Merkle proofs for token +/// distribution. MerkleBase enables Airstreams, a portmanteau of "airdrop" and "stream". This is an airdrop model +/// where the tokens are distributed over time, as opposed to all at once. On the other hand, MerkleInstant enables +/// instant airdrops where tokens are unlocked and distributed immediately. See the Sablier docs for more guidance: +/// https://docs.sablier.com +/// @dev Deploys MerkleBase and MerkleInstant campaigns with CREATE2. +interface ISablierMerkleFactory { /*////////////////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////////////////*/ @@ -20,7 +25,7 @@ interface ISablierMerkleLockupFactory { /// @notice Emitted when a {SablierV2MerkleInstant} campaign is created. event CreateMerkleInstant( ISablierMerkleInstant indexed merkleInstant, - MerkleLockup.ConstructorParams baseParams, + MerkleBase.ConstructorParams baseParams, uint256 aggregateAmount, uint256 recipientCount ); @@ -28,8 +33,10 @@ interface ISablierMerkleLockupFactory { /// @notice Emitted when a {SablierMerkleLL} campaign is created. event CreateMerkleLL( ISablierMerkleLL indexed merkleLL, - MerkleLockup.ConstructorParams baseParams, + MerkleBase.ConstructorParams baseParams, ISablierLockupLinear lockupLinear, + bool cancelable, + bool transferable, LockupLinear.Durations streamDurations, uint256 aggregateAmount, uint256 recipientCount @@ -38,8 +45,10 @@ interface ISablierMerkleLockupFactory { /// @notice Emitted when a {SablierMerkleLT} campaign is created. event CreateMerkleLT( ISablierMerkleLT indexed merkleLT, - MerkleLockup.ConstructorParams baseParams, + MerkleBase.ConstructorParams baseParams, ISablierLockupTranched lockupTranched, + bool cancelable, + bool transferable, MerkleLT.TrancheWithPercentage[] tranchesWithPercentages, uint256 totalDuration, uint256 aggregateAmount, @@ -63,32 +72,37 @@ interface ISablierMerkleLockupFactory { NON-CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ - /// @notice Creates a new MerkleLockup campaign for instant distribution of assets. + /// @notice Creates a new MerkleInstant campaign for instant distribution of assets. /// @dev Emits a {CreateMerkleInstant} event. - /// @param baseParams Struct encapsulating the {SablierV2MerkleLockup} parameters, which are documented in + /// @param baseParams Struct encapsulating the {SablierMerkleBase} parameters, which are documented in /// {DataTypes}. /// @param aggregateAmount The total amount of ERC-20 assets to be distributed to all recipients. /// @param recipientCount The total number of recipients who are eligible to claim. + /// @return merkleInstant The address of the newly created MerkleInstant contract. function createMerkleInstant( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, uint256 aggregateAmount, uint256 recipientCount ) external - returns (ISablierMerkleInstant merkleLL); + returns (ISablierMerkleInstant merkleInstant); - /// @notice Creates a new MerkleLockup campaign with a LockupLinear distribution. + /// @notice Creates a new MerkleBase campaign with a LockupLinear distribution. /// @dev Emits a {CreateMerkleLL} event. - /// @param baseParams Struct encapsulating the {SablierMerkleLockup} parameters, which are documented in + /// @param baseParams Struct encapsulating the {SablierMerkleBase} parameters, which are documented in /// {DataTypes}. /// @param lockupLinear The address of the {SablierLockupLinear} contract. + /// @param cancelable Indicates if the stream will be cancelable after claiming. + /// @param transferable Indicates if the stream will be transferable after claiming. /// @param streamDurations The durations for each stream. /// @param aggregateAmount The total amount of ERC-20 assets to be distributed to all recipients. /// @param recipientCount The total number of recipients who are eligible to claim. - /// @return merkleLL The address of the newly created MerkleLockup contract. + /// @return merkleLL The address of the newly created MerkleBase contract. function createMerkleLL( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, ISablierLockupLinear lockupLinear, + bool cancelable, + bool transferable, LockupLinear.Durations memory streamDurations, uint256 aggregateAmount, uint256 recipientCount @@ -96,19 +110,23 @@ interface ISablierMerkleLockupFactory { external returns (ISablierMerkleLL merkleLL); - /// @notice Creates a new MerkleLockup campaign with a LockupTranched distribution. + /// @notice Creates a new MerkleBase campaign with a LockupTranched distribution. /// @dev Emits a {CreateMerkleLT} event. /// - /// @param baseParams Struct encapsulating the {SablierMerkleLockup} parameters, which are documented in + /// @param baseParams Struct encapsulating the {SablierMerkleBase} parameters, which are documented in /// {DataTypes}. /// @param lockupTranched The address of the {SablierLockupTranched} contract. + /// @param cancelable Indicates if the stream will be cancelable after claiming. + /// @param transferable Indicates if the stream will be transferable after claiming. /// @param tranchesWithPercentages The tranches with their respective unlock percentages. /// @param aggregateAmount The total amount of ERC-20 assets to be distributed to all recipients. /// @param recipientCount The total number of recipients who are eligible to claim. - /// @return merkleLT The address of the newly created MerkleLockup contract. + /// @return merkleLT The address of the newly created MerkleBase contract. function createMerkleLT( - MerkleLockup.ConstructorParams memory baseParams, + MerkleBase.ConstructorParams memory baseParams, ISablierLockupTranched lockupTranched, + bool cancelable, + bool transferable, MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages, uint256 aggregateAmount, uint256 recipientCount diff --git a/src/periphery/interfaces/ISablierMerkleInstant.sol b/src/periphery/interfaces/ISablierMerkleInstant.sol index 03d227570..656f47139 100644 --- a/src/periphery/interfaces/ISablierMerkleInstant.sol +++ b/src/periphery/interfaces/ISablierMerkleInstant.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.22; -import { ISablierMerkleLockup } from "./ISablierMerkleLockup.sol"; +import { ISablierMerkleBase } from "./ISablierMerkleBase.sol"; /// @title ISablierMerkleInstant -/// @notice MerkleLockup campaign that facilitates instant distribution of assets. -interface ISablierMerkleInstant is ISablierMerkleLockup { +/// @notice MerkleInstant enables instant airdrop campaigns. +interface ISablierMerkleInstant is ISablierMerkleBase { /*////////////////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////////////////*/ diff --git a/src/periphery/interfaces/ISablierMerkleLL.sol b/src/periphery/interfaces/ISablierMerkleLL.sol index 2c16e587a..7d8099997 100644 --- a/src/periphery/interfaces/ISablierMerkleLL.sol +++ b/src/periphery/interfaces/ISablierMerkleLL.sol @@ -3,11 +3,11 @@ pragma solidity >=0.8.22; import { ISablierLockupLinear } from "../../core/interfaces/ISablierLockupLinear.sol"; -import { ISablierMerkleLockup } from "./ISablierMerkleLockup.sol"; +import { ISablierMerkleBase } from "./ISablierMerkleBase.sol"; /// @title ISablierMerkleLL -/// @notice MerkleLockup campaign that creates LockupLinear streams. -interface ISablierMerkleLL is ISablierMerkleLockup { +/// @notice MerkleBase campaign that creates LockupLinear streams. +interface ISablierMerkleLL is ISablierMerkleBase { /*////////////////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////////////////*/ diff --git a/src/periphery/interfaces/ISablierMerkleLT.sol b/src/periphery/interfaces/ISablierMerkleLT.sol index acd599d26..37caddf2e 100644 --- a/src/periphery/interfaces/ISablierMerkleLT.sol +++ b/src/periphery/interfaces/ISablierMerkleLT.sol @@ -3,12 +3,12 @@ pragma solidity >=0.8.22; import { ISablierLockupTranched } from "../../core/interfaces/ISablierLockupTranched.sol"; -import { ISablierMerkleLockup } from "./ISablierMerkleLockup.sol"; +import { ISablierMerkleBase } from "./ISablierMerkleBase.sol"; import { MerkleLT } from "../types/DataTypes.sol"; /// @title ISablierMerkleLT -/// @notice MerkleLockup campaign that creates LockupTranched streams. -interface ISablierMerkleLT is ISablierMerkleLockup { +/// @notice MerkleBase campaign that creates LockupTranched streams. +interface ISablierMerkleLT is ISablierMerkleBase { /*////////////////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////////////////*/ diff --git a/src/periphery/libraries/Errors.sol b/src/periphery/libraries/Errors.sol index 6e86878c3..131a91d1f 100644 --- a/src/periphery/libraries/Errors.sol +++ b/src/periphery/libraries/Errors.sol @@ -11,24 +11,24 @@ library Errors { error SablierBatchLockup_BatchSizeZero(); /*////////////////////////////////////////////////////////////////////////// - SABLIER-MERKLE-LOCKUP + SABLIER-MERKLE-BASE //////////////////////////////////////////////////////////////////////////*/ /// @notice Thrown when trying to claim after the campaign has expired. - error SablierMerkleLockup_CampaignExpired(uint256 blockTimestamp, uint40 expiration); + error SablierMerkleBase_CampaignExpired(uint256 blockTimestamp, uint40 expiration); /// @notice Thrown when trying to create a campaign with a name that is too long. - error SablierMerkleLockup_CampaignNameTooLong(uint256 nameLength, uint256 maxLength); + error SablierMerkleBase_CampaignNameTooLong(uint256 nameLength, uint256 maxLength); /// @notice Thrown when trying to clawback when the current timestamp is over the grace period and the campaign has /// not expired. - error SablierMerkleLockup_ClawbackNotAllowed(uint256 blockTimestamp, uint40 expiration, uint40 firstClaimTime); + error SablierMerkleBase_ClawbackNotAllowed(uint256 blockTimestamp, uint40 expiration, uint40 firstClaimTime); /// @notice Thrown when trying to claim with an invalid Merkle proof. - error SablierMerkleLockup_InvalidProof(); + error SablierMerkleBase_InvalidProof(); /// @notice Thrown when trying to claim the same stream more than once. - error SablierMerkleLockup_StreamClaimed(uint256 index); + error SablierMerkleBase_StreamClaimed(uint256 index); /*////////////////////////////////////////////////////////////////////////// SABLIER-MERKLE-LT diff --git a/src/periphery/types/DataTypes.sol b/src/periphery/types/DataTypes.sol index 17559fa32..7480b503e 100644 --- a/src/periphery/types/DataTypes.sol +++ b/src/periphery/types/DataTypes.sol @@ -82,27 +82,21 @@ library BatchLockup { } } -library MerkleLockup { - /// @notice Struct encapsulating the base constructor parameters of a MerkleLockup campaign. +library MerkleBase { + /// @notice Struct encapsulating the base constructor parameters of a Merkle campaign. /// @param asset The contract address of the ERC-20 asset to be distributed. - /// @param cancelable Indicates if the stream will be cancelable after claiming. This does not apply to - /// {SablierMerkleInstant}. /// @param expiration The expiration of the campaign, as a Unix timestamp. - /// @param initialAdmin The initial admin of the MerkleLockup campaign. + /// @param initialAdmin The initial admin of the campaign. /// @param ipfsCID The content identifier for indexing the contract on IPFS. /// @param merkleRoot The Merkle root of the claim data. /// @param name The name of the campaign. - /// @param transferable Indicates if the stream will be transferable after claiming. This only applies to - /// {SablierMerkleInstant}. struct ConstructorParams { IERC20 asset; - bool cancelable; uint40 expiration; address initialAdmin; string ipfsCID; bytes32 merkleRoot; string name; - bool transferable; } } diff --git a/test/Base.t.sol b/test/Base.t.sol index 3d7622b04..557232868 100644 --- a/test/Base.t.sol +++ b/test/Base.t.sol @@ -12,12 +12,12 @@ import { SablierLockupLinear } from "src/core/SablierLockupLinear.sol"; import { SablierLockupTranched } from "src/core/SablierLockupTranched.sol"; import { SablierNFTDescriptor } from "src/core/SablierNFTDescriptor.sol"; import { LockupDynamic, LockupLinear, LockupTranched } from "src/core/types/DataTypes.sol"; -import { ISablierMerkleLockupFactory } from "src/periphery/interfaces/ISablierMerkleLockupFactory.sol"; import { ISablierBatchLockup } from "src/periphery/interfaces/ISablierBatchLockup.sol"; +import { ISablierMerkleFactory } from "src/periphery/interfaces/ISablierMerkleFactory.sol"; import { ISablierMerkleLL } from "src/periphery/interfaces/ISablierMerkleLL.sol"; import { ISablierMerkleLT } from "src/periphery/interfaces/ISablierMerkleLT.sol"; import { SablierBatchLockup } from "src/periphery/SablierBatchLockup.sol"; -import { SablierMerkleLockupFactory } from "src/periphery/SablierMerkleLockupFactory.sol"; +import { SablierMerkleFactory } from "src/periphery/SablierMerkleFactory.sol"; import { ERC20Mock } from "./mocks/erc20/ERC20Mock.sol"; import { ERC20MissingReturn } from "./mocks/erc20/ERC20MissingReturn.sol"; @@ -50,7 +50,7 @@ abstract contract Base_Test is Assertions, Calculations, Constants, DeployOptimi ISablierLockupDynamic internal lockupDynamic; ISablierLockupLinear internal lockupLinear; ISablierLockupTranched internal lockupTranched; - ISablierMerkleLockupFactory internal merkleLockupFactory; + ISablierMerkleFactory internal merkleFactory; ISablierMerkleLL internal merkleLL; ISablierMerkleLT internal merkleLT; ISablierNFTDescriptor internal nftDescriptor; @@ -123,12 +123,12 @@ abstract contract Base_Test is Assertions, Calculations, Constants, DeployOptimi dai.approve({ spender: address(lockupLinear), value: MAX_UINT256 }); dai.approve({ spender: address(lockupDynamic), value: MAX_UINT256 }); dai.approve({ spender: address(lockupTranched), value: MAX_UINT256 }); - dai.approve({ spender: address(merkleLockupFactory), value: MAX_UINT256 }); + dai.approve({ spender: address(merkleFactory), value: MAX_UINT256 }); usdt.approve({ spender: address(batchLockup), value: MAX_UINT256 }); usdt.approve({ spender: address(lockupLinear), value: MAX_UINT256 }); usdt.approve({ spender: address(lockupDynamic), value: MAX_UINT256 }); usdt.approve({ spender: address(lockupTranched), value: MAX_UINT256 }); - usdt.approve({ spender: address(merkleLockupFactory), value: MAX_UINT256 }); + usdt.approve({ spender: address(merkleFactory), value: MAX_UINT256 }); } /// @dev Generates a user, labels its address, funds it with test assets, and approves the protocol contracts. @@ -153,9 +153,9 @@ abstract contract Base_Test is Assertions, Calculations, Constants, DeployOptimi lockupDynamic = new SablierLockupDynamic(users.admin, nftDescriptor, defaults.MAX_SEGMENT_COUNT()); lockupLinear = new SablierLockupLinear(users.admin, nftDescriptor); lockupTranched = new SablierLockupTranched(users.admin, nftDescriptor, defaults.MAX_TRANCHE_COUNT()); - merkleLockupFactory = new SablierMerkleLockupFactory(); + merkleFactory = new SablierMerkleFactory(); } else { - (lockupDynamic, lockupLinear, lockupTranched, nftDescriptor, batchLockup, merkleLockupFactory) = + (lockupDynamic, lockupLinear, lockupTranched, nftDescriptor, batchLockup, merkleFactory) = deployOptimizedProtocol(users.admin, defaults.MAX_SEGMENT_COUNT(), defaults.MAX_TRANCHE_COUNT()); } @@ -163,7 +163,7 @@ abstract contract Base_Test is Assertions, Calculations, Constants, DeployOptimi vm.label({ account: address(lockupDynamic), newLabel: "LockupDynamic" }); vm.label({ account: address(lockupLinear), newLabel: "LockupLinear" }); vm.label({ account: address(lockupTranched), newLabel: "LockupTranched" }); - vm.label({ account: address(merkleLockupFactory), newLabel: "MerkleLockupFactory" }); + vm.label({ account: address(merkleFactory), newLabel: "MerkleFactory" }); vm.label({ account: address(nftDescriptor), newLabel: "NFTDescriptor" }); } diff --git a/test/periphery/Periphery.t.sol b/test/periphery/Periphery.t.sol index 0e2726bdb..4d90fb822 100644 --- a/test/periphery/Periphery.t.sol +++ b/test/periphery/Periphery.t.sol @@ -35,14 +35,14 @@ contract Periphery_Test is Base_Test { abi.encodePacked( caller, address(asset_), - defaults.CANCELABLE(), expiration, admin, abi.encode(defaults.IPFS_CID()), merkleRoot, defaults.NAME_BYTES32(), - defaults.TRANSFERABLE(), lockupLinear, + defaults.CANCELABLE(), + defaults.TRANSFERABLE(), abi.encode(defaults.durations()) ) ); @@ -50,7 +50,7 @@ contract Periphery_Test is Base_Test { return vm.computeCreate2Address({ salt: salt, initCodeHash: creationBytecodeHash, - deployer: address(merkleLockupFactory) + deployer: address(merkleFactory) }); } @@ -69,14 +69,14 @@ contract Periphery_Test is Base_Test { abi.encodePacked( caller, address(asset_), - defaults.CANCELABLE(), expiration, admin, abi.encode(defaults.IPFS_CID()), merkleRoot, defaults.NAME_BYTES32(), - defaults.TRANSFERABLE(), lockupTranched, + defaults.CANCELABLE(), + defaults.TRANSFERABLE(), abi.encode(defaults.tranchesWithPercentages()) ) ); @@ -84,7 +84,7 @@ contract Periphery_Test is Base_Test { return vm.computeCreate2Address({ salt: salt, initCodeHash: creationBytecodeHash, - deployer: address(merkleLockupFactory) + deployer: address(merkleFactory) }); } @@ -98,8 +98,13 @@ contract Periphery_Test is Base_Test { view returns (bytes memory) { - bytes memory constructorArgs = - abi.encode(defaults.baseParams(admin, asset_, expiration, merkleRoot), lockupLinear, defaults.durations()); + bytes memory constructorArgs = abi.encode( + defaults.baseParams(admin, asset_, expiration, merkleRoot), + lockupLinear, + defaults.CANCELABLE(), + defaults.TRANSFERABLE(), + defaults.durations() + ); if (!isTestOptimizedProfile()) { return bytes.concat(type(SablierMerkleLL).creationCode, constructorArgs); } else { @@ -120,6 +125,8 @@ contract Periphery_Test is Base_Test { bytes memory constructorArgs = abi.encode( defaults.baseParams(admin, asset_, expiration, merkleRoot), lockupTranched, + defaults.CANCELABLE(), + defaults.TRANSFERABLE(), defaults.tranchesWithPercentages() ); if (!isTestOptimizedProfile()) { diff --git a/test/periphery/fork/merkle-lockup/MerkleLL.t.sol b/test/periphery/fork/merkle-lockup/MerkleLL.t.sol index 9f470a51d..6e41d245d 100644 --- a/test/periphery/fork/merkle-lockup/MerkleLL.t.sol +++ b/test/periphery/fork/merkle-lockup/MerkleLL.t.sol @@ -6,7 +6,7 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { Lockup, LockupLinear } from "src/core/types/DataTypes.sol"; import { ISablierMerkleLL } from "src/periphery/interfaces/ISablierMerkleLL.sol"; -import { MerkleLockup } from "src/periphery/types/DataTypes.sol"; +import { MerkleBase } from "src/periphery/types/DataTypes.sol"; import { MerkleBuilder } from "../../../utils/MerkleBuilder.sol"; import { Fork_Test } from "../Fork.t.sol"; @@ -39,7 +39,8 @@ abstract contract MerkleLL_Fork_Test is Fork_Test { uint256 actualStreamId; uint256 aggregateAmount; uint128[] amounts; - MerkleLockup.ConstructorParams baseParams; + MerkleBase.ConstructorParams baseParams; + bool cancelable; uint128 clawbackAmount; address expectedLL; LockupLinear.StreamLL expectedStream; @@ -52,6 +53,7 @@ abstract contract MerkleLL_Fork_Test is Fork_Test { bytes32 merkleRoot; address[] recipients; uint256 recipientCount; + bool transferable; } // We need the leaves as a storage variable so that we can use OpenZeppelin's {Arrays.findUpperBound}. @@ -116,25 +118,29 @@ abstract contract MerkleLL_Fork_Test is Fork_Test { expiration: params.expiration }); - vm.expectEmit({ emitter: address(merkleLockupFactory) }); + vm.expectEmit({ emitter: address(merkleFactory) }); emit CreateMerkleLL({ merkleLL: ISablierMerkleLL(vars.expectedLL), baseParams: vars.baseParams, lockupLinear: lockupLinear, + cancelable: vars.cancelable, + transferable: defaults.TRANSFERABLE(), streamDurations: defaults.durations(), aggregateAmount: vars.aggregateAmount, recipientCount: vars.recipientCount }); - vars.merkleLL = merkleLockupFactory.createMerkleLL({ + vars.merkleLL = merkleFactory.createMerkleLL({ baseParams: vars.baseParams, lockupLinear: lockupLinear, + cancelable: vars.cancelable, + transferable: vars.transferable, streamDurations: defaults.durations(), aggregateAmount: vars.aggregateAmount, recipientCount: vars.recipientCount }); - // Fund the MerkleLockup contract. + // Fund the MerkleBase contract. deal({ token: address(FORK_ASSET), to: address(vars.merkleLL), give: vars.aggregateAmount }); assertGt(address(vars.merkleLL).code.length, 0, "MerkleLL contract not created"); diff --git a/test/periphery/fork/merkle-lockup/MerkleLT.t.sol b/test/periphery/fork/merkle-lockup/MerkleLT.t.sol index 1fa90b38d..562ae266f 100644 --- a/test/periphery/fork/merkle-lockup/MerkleLT.t.sol +++ b/test/periphery/fork/merkle-lockup/MerkleLT.t.sol @@ -6,7 +6,7 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { Lockup, LockupTranched } from "src/core/types/DataTypes.sol"; import { ISablierMerkleLT } from "src/periphery/interfaces/ISablierMerkleLT.sol"; -import { MerkleLockup } from "src/periphery/types/DataTypes.sol"; +import { MerkleBase } from "src/periphery/types/DataTypes.sol"; import { MerkleBuilder } from "../../../utils/MerkleBuilder.sol"; import { Fork_Test } from "../Fork.t.sol"; @@ -40,7 +40,8 @@ abstract contract MerkleLT_Fork_Test is Fork_Test { LockupTranched.Tranche[] actualTranches; uint256 aggregateAmount; uint128[] amounts; - MerkleLockup.ConstructorParams baseParams; + MerkleBase.ConstructorParams baseParams; + bool cancelable; uint128 clawbackAmount; address expectedLT; LockupTranched.StreamLT expectedStream; @@ -53,6 +54,7 @@ abstract contract MerkleLT_Fork_Test is Fork_Test { bytes32 merkleRoot; address[] recipients; uint256 recipientCount; + bool transferable; } // We need the leaves as a storage variable so that we can use OpenZeppelin's {Arrays.findUpperBound}. @@ -117,26 +119,30 @@ abstract contract MerkleLT_Fork_Test is Fork_Test { expiration: params.expiration }); - vm.expectEmit({ emitter: address(merkleLockupFactory) }); + vm.expectEmit({ emitter: address(merkleFactory) }); emit CreateMerkleLT({ merkleLT: ISablierMerkleLT(vars.expectedLT), baseParams: vars.baseParams, lockupTranched: lockupTranched, + cancelable: vars.cancelable, + transferable: vars.transferable, tranchesWithPercentages: defaults.tranchesWithPercentages(), totalDuration: defaults.TOTAL_DURATION(), aggregateAmount: vars.aggregateAmount, recipientCount: vars.recipientCount }); - vars.merkleLT = merkleLockupFactory.createMerkleLT({ + vars.merkleLT = merkleFactory.createMerkleLT({ baseParams: vars.baseParams, lockupTranched: lockupTranched, + cancelable: vars.cancelable, + transferable: vars.transferable, tranchesWithPercentages: defaults.tranchesWithPercentages(), aggregateAmount: vars.aggregateAmount, recipientCount: vars.recipientCount }); - // Fund the MerkleLockup contract. + // Fund the MerkleBase contract. deal({ token: address(FORK_ASSET), to: address(vars.merkleLT), give: vars.aggregateAmount }); assertGt(address(vars.merkleLT).code.length, 0, "MerkleLT contract not created"); diff --git a/test/periphery/integration/merkle-lockup/MerkleLockup.t.sol b/test/periphery/integration/merkle-lockup/MerkleLockup.t.sol index 1110f26e9..63c048ade 100644 --- a/test/periphery/integration/merkle-lockup/MerkleLockup.t.sol +++ b/test/periphery/integration/merkle-lockup/MerkleLockup.t.sol @@ -13,11 +13,11 @@ abstract contract MerkleLockup_Integration_Test is Periphery_Test { // Make Alice the caller. resetPrank(users.alice); - // Create the default MerkleLockup contracts. + // Create the default MerkleBase contracts. merkleLL = createMerkleLL(); merkleLT = createMerkleLT(); - // Fund the MerkleLockup contracts. + // Fund the MerkleBase contracts. deal({ token: address(dai), to: address(merkleLL), give: defaults.AGGREGATE_AMOUNT() }); deal({ token: address(dai), to: address(merkleLT), give: defaults.AGGREGATE_AMOUNT() }); } @@ -76,9 +76,11 @@ abstract contract MerkleLockup_Integration_Test is Periphery_Test { } function createMerkleLL(address admin, uint40 expiration) internal returns (ISablierMerkleLL) { - return merkleLockupFactory.createMerkleLL({ + return merkleFactory.createMerkleLL({ baseParams: defaults.baseParams(admin, dai, expiration, defaults.MERKLE_ROOT()), lockupLinear: lockupLinear, + cancelable: defaults.CANCELABLE(), + transferable: defaults.TRANSFERABLE(), streamDurations: defaults.durations(), aggregateAmount: defaults.AGGREGATE_AMOUNT(), recipientCount: defaults.RECIPIENT_COUNT() @@ -139,9 +141,11 @@ abstract contract MerkleLockup_Integration_Test is Periphery_Test { } function createMerkleLT(address admin, uint40 expiration) internal returns (ISablierMerkleLT) { - return merkleLockupFactory.createMerkleLT({ + return merkleFactory.createMerkleLT({ baseParams: defaults.baseParams(admin, dai, expiration, defaults.MERKLE_ROOT()), lockupTranched: lockupTranched, + cancelable: defaults.CANCELABLE(), + transferable: defaults.TRANSFERABLE(), tranchesWithPercentages: defaults.tranchesWithPercentages(), aggregateAmount: defaults.AGGREGATE_AMOUNT(), recipientCount: defaults.RECIPIENT_COUNT() diff --git a/test/periphery/integration/merkle-lockup/factory/create-merkle-ll/createMerkleLL.t.sol b/test/periphery/integration/merkle-lockup/factory/create-merkle-ll/createMerkleLL.t.sol index 5cab524aa..8764a4f88 100644 --- a/test/periphery/integration/merkle-lockup/factory/create-merkle-ll/createMerkleLL.t.sol +++ b/test/periphery/integration/merkle-lockup/factory/create-merkle-ll/createMerkleLL.t.sol @@ -4,13 +4,15 @@ pragma solidity >=0.8.22 <0.9.0; import { LockupLinear } from "src/core/types/DataTypes.sol"; import { Errors } from "src/periphery/libraries/Errors.sol"; import { ISablierMerkleLL } from "src/periphery/interfaces/ISablierMerkleLL.sol"; -import { MerkleLockup } from "src/periphery/types/DataTypes.sol"; +import { MerkleBase } from "src/periphery/types/DataTypes.sol"; import { MerkleLockup_Integration_Test } from "../../MerkleLockup.t.sol"; contract CreateMerkleLL_Integration_Test is MerkleLockup_Integration_Test { function test_RevertWhen_CampaignNameTooLong() external { - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); + bool cancelable = defaults.CANCELABLE(); + bool transferable = defaults.TRANSFERABLE(); LockupLinear.Durations memory streamDurations = defaults.durations(); uint256 aggregateAmount = defaults.AGGREGATE_AMOUNT(); uint256 recipientCount = defaults.RECIPIENT_COUNT(); @@ -19,13 +21,15 @@ contract CreateMerkleLL_Integration_Test is MerkleLockup_Integration_Test { vm.expectRevert( abi.encodeWithSelector( - Errors.SablierMerkleLockup_CampaignNameTooLong.selector, bytes(baseParams.name).length, 32 + Errors.SablierMerkleBase_CampaignNameTooLong.selector, bytes(baseParams.name).length, 32 ) ); - merkleLockupFactory.createMerkleLL({ + merkleFactory.createMerkleLL({ baseParams: baseParams, lockupLinear: lockupLinear, + cancelable: cancelable, + transferable: transferable, streamDurations: streamDurations, aggregateAmount: aggregateAmount, recipientCount: recipientCount @@ -36,18 +40,22 @@ contract CreateMerkleLL_Integration_Test is MerkleLockup_Integration_Test { _; } - /// @dev This test works because a default MerkleLockup contract is deployed in {Integration_Test.setUp} + /// @dev This test works because a default MerkleBase contract is deployed in {Integration_Test.setUp} function test_RevertGiven_CreatedAlready() external whenCampaignNameNotTooLong { - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); + bool cancelable = defaults.CANCELABLE(); + bool transferable = defaults.TRANSFERABLE(); LockupLinear.Durations memory streamDurations = defaults.durations(); uint256 aggregateAmount = defaults.AGGREGATE_AMOUNT(); uint256 recipientCount = defaults.RECIPIENT_COUNT(); // Expect a revert due to CREATE2. vm.expectRevert(); - merkleLockupFactory.createMerkleLL({ + merkleFactory.createMerkleLL({ baseParams: baseParams, lockupLinear: lockupLinear, + cancelable: cancelable, + transferable: transferable, streamDurations: streamDurations, aggregateAmount: aggregateAmount, recipientCount: recipientCount @@ -69,18 +77,20 @@ contract CreateMerkleLL_Integration_Test is MerkleLockup_Integration_Test { vm.assume(admin != users.admin); address expectedLL = computeMerkleLLAddress(admin, expiration); - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams({ + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams({ admin: admin, asset_: dai, merkleRoot: defaults.MERKLE_ROOT(), expiration: expiration }); - vm.expectEmit({ emitter: address(merkleLockupFactory) }); + vm.expectEmit({ emitter: address(merkleFactory) }); emit CreateMerkleLL({ merkleLL: ISablierMerkleLL(expectedLL), baseParams: baseParams, lockupLinear: lockupLinear, + cancelable: defaults.CANCELABLE(), + transferable: defaults.TRANSFERABLE(), streamDurations: defaults.durations(), aggregateAmount: defaults.AGGREGATE_AMOUNT(), recipientCount: defaults.RECIPIENT_COUNT() diff --git a/test/periphery/integration/merkle-lockup/factory/create-merkle-lt/createMerkleLT.t.sol b/test/periphery/integration/merkle-lockup/factory/create-merkle-lt/createMerkleLT.t.sol index fa03eb990..f52e9441e 100644 --- a/test/periphery/integration/merkle-lockup/factory/create-merkle-lt/createMerkleLT.t.sol +++ b/test/periphery/integration/merkle-lockup/factory/create-merkle-lt/createMerkleLT.t.sol @@ -3,13 +3,15 @@ pragma solidity >=0.8.22 <0.9.0; import { Errors } from "src/periphery/libraries/Errors.sol"; import { ISablierMerkleLT } from "src/periphery/interfaces/ISablierMerkleLT.sol"; -import { MerkleLockup, MerkleLT } from "src/periphery/types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "src/periphery/types/DataTypes.sol"; import { MerkleLockup_Integration_Test } from "../../MerkleLockup.t.sol"; contract CreateMerkleLT_Integration_Test is MerkleLockup_Integration_Test { function test_RevertWhen_CampaignNameTooLong() external { - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); + bool cancelable = defaults.CANCELABLE(); + bool transferable = defaults.TRANSFERABLE(); MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages = defaults.tranchesWithPercentages(); uint256 aggregateAmount = defaults.AGGREGATE_AMOUNT(); uint256 recipientCount = defaults.RECIPIENT_COUNT(); @@ -18,12 +20,18 @@ contract CreateMerkleLT_Integration_Test is MerkleLockup_Integration_Test { vm.expectRevert( abi.encodeWithSelector( - Errors.SablierMerkleLockup_CampaignNameTooLong.selector, bytes(baseParams.name).length, 32 + Errors.SablierMerkleBase_CampaignNameTooLong.selector, bytes(baseParams.name).length, 32 ) ); - merkleLockupFactory.createMerkleLT( - baseParams, lockupTranched, tranchesWithPercentages, aggregateAmount, recipientCount + merkleFactory.createMerkleLT( + baseParams, + lockupTranched, + cancelable, + transferable, + tranchesWithPercentages, + aggregateAmount, + recipientCount ); } @@ -31,17 +39,25 @@ contract CreateMerkleLT_Integration_Test is MerkleLockup_Integration_Test { _; } - /// @dev This test works because a default MerkleLockup contract is deployed in {Integration_Test.setUp} + /// @dev This test works because a default MerkleBase contract is deployed in {Integration_Test.setUp} function test_RevertGiven_CreatedAlready() external whenCampaignNameNotTooLong { - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); + bool cancelable = defaults.CANCELABLE(); + bool transferable = defaults.TRANSFERABLE(); MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages = defaults.tranchesWithPercentages(); uint256 aggregateAmount = defaults.AGGREGATE_AMOUNT(); uint256 recipientCount = defaults.RECIPIENT_COUNT(); // Expect a revert due to CREATE2. vm.expectRevert(); - merkleLockupFactory.createMerkleLT( - baseParams, lockupTranched, tranchesWithPercentages, aggregateAmount, recipientCount + merkleFactory.createMerkleLT( + baseParams, + lockupTranched, + cancelable, + transferable, + tranchesWithPercentages, + aggregateAmount, + recipientCount ); } @@ -60,18 +76,20 @@ contract CreateMerkleLT_Integration_Test is MerkleLockup_Integration_Test { vm.assume(admin != users.admin); address expectedLT = computeMerkleLTAddress(admin, expiration); - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams({ + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams({ admin: admin, asset_: dai, merkleRoot: defaults.MERKLE_ROOT(), expiration: expiration }); - vm.expectEmit({ emitter: address(merkleLockupFactory) }); + vm.expectEmit({ emitter: address(merkleFactory) }); emit CreateMerkleLT({ merkleLT: ISablierMerkleLT(expectedLT), baseParams: baseParams, lockupTranched: lockupTranched, + cancelable: defaults.CANCELABLE(), + transferable: defaults.TRANSFERABLE(), tranchesWithPercentages: defaults.tranchesWithPercentages(), totalDuration: defaults.TOTAL_DURATION(), aggregateAmount: defaults.AGGREGATE_AMOUNT(), diff --git a/test/periphery/integration/merkle-lockup/factory/is-percentages-sum-100/isPercentagesSum100.t.sol b/test/periphery/integration/merkle-lockup/factory/is-percentages-sum-100/isPercentagesSum100.t.sol index 60f753642..1d2893564 100644 --- a/test/periphery/integration/merkle-lockup/factory/is-percentages-sum-100/isPercentagesSum100.t.sol +++ b/test/periphery/integration/merkle-lockup/factory/is-percentages-sum-100/isPercentagesSum100.t.sol @@ -13,7 +13,7 @@ contract IsPercentagesSum100_Integration_Test is MerkleLockup_Integration_Test { tranches[0].unlockPercentage = MAX_UD2x18; vm.expectRevert(); - merkleLockupFactory.isPercentagesSum100(tranches); + merkleFactory.isPercentagesSum100(tranches); } modifier whenSumDoesNotOverflow() { @@ -34,7 +34,7 @@ contract IsPercentagesSum100_Integration_Test is MerkleLockup_Integration_Test { tranchesWithPercentages[0].unlockPercentage = ud2x18(0.05e18); tranchesWithPercentages[1].unlockPercentage = ud2x18(0.2e18); - assertFalse(merkleLockupFactory.isPercentagesSum100(tranchesWithPercentages), "isPercentagesSum100"); + assertFalse(merkleFactory.isPercentagesSum100(tranchesWithPercentages), "isPercentagesSum100"); } function test_TotalPercentageGreaterThanOneHundred() @@ -47,7 +47,7 @@ contract IsPercentagesSum100_Integration_Test is MerkleLockup_Integration_Test { tranchesWithPercentages[0].unlockPercentage = ud2x18(0.5e18); tranchesWithPercentages[1].unlockPercentage = ud2x18(0.6e18); - assertFalse(merkleLockupFactory.isPercentagesSum100(tranchesWithPercentages), "isPercentagesSum100"); + assertFalse(merkleFactory.isPercentagesSum100(tranchesWithPercentages), "isPercentagesSum100"); } modifier whenTotalPercentageOneHundred() { @@ -55,6 +55,6 @@ contract IsPercentagesSum100_Integration_Test is MerkleLockup_Integration_Test { } function test_IsPercentagesSum100() external view whenSumDoesNotOverflow whenTotalPercentageOneHundred { - assertTrue(merkleLockupFactory.isPercentagesSum100(defaults.tranchesWithPercentages()), "isPercentagesSum100"); + assertTrue(merkleFactory.isPercentagesSum100(defaults.tranchesWithPercentages()), "isPercentagesSum100"); } } diff --git a/test/periphery/integration/merkle-lockup/ll/claim/claim.t.sol b/test/periphery/integration/merkle-lockup/ll/claim/claim.t.sol index 44b234cd4..2a682dcc1 100644 --- a/test/periphery/integration/merkle-lockup/ll/claim/claim.t.sol +++ b/test/periphery/integration/merkle-lockup/ll/claim/claim.t.sol @@ -16,9 +16,7 @@ contract Claim_Integration_Test is MerkleLockup_Integration_Test { uint256 warpTime = expiration + 1 seconds; bytes32[] memory merkleProof; vm.warp({ newTimestamp: warpTime }); - vm.expectRevert( - abi.encodeWithSelector(Errors.SablierMerkleLockup_CampaignExpired.selector, warpTime, expiration) - ); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_CampaignExpired.selector, warpTime, expiration)); merkleLL.claim({ index: 1, recipient: users.recipient1, amount: 1, merkleProof: merkleProof }); } @@ -31,7 +29,7 @@ contract Claim_Integration_Test is MerkleLockup_Integration_Test { uint256 index1 = defaults.INDEX1(); uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_StreamClaimed.selector, index1)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_StreamClaimed.selector, index1)); merkleLL.claim(index1, users.recipient1, amount, merkleProof); } @@ -52,7 +50,7 @@ contract Claim_Integration_Test is MerkleLockup_Integration_Test { uint256 invalidIndex = 1337; uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLL.claim(invalidIndex, users.recipient1, amount, merkleProof); } @@ -66,7 +64,7 @@ contract Claim_Integration_Test is MerkleLockup_Integration_Test { address invalidRecipient = address(1337); uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLL.claim(index1, invalidRecipient, amount, merkleProof); } @@ -79,7 +77,7 @@ contract Claim_Integration_Test is MerkleLockup_Integration_Test { uint256 index1 = defaults.INDEX1(); uint128 invalidAmount = 1337; bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLL.claim(index1, users.recipient1, invalidAmount, merkleProof); } @@ -92,7 +90,7 @@ contract Claim_Integration_Test is MerkleLockup_Integration_Test { uint256 index1 = defaults.INDEX1(); uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory invalidMerkleProof = defaults.index2Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLL.claim(index1, users.recipient1, amount, invalidMerkleProof); } diff --git a/test/periphery/integration/merkle-lockup/ll/clawback/clawback.t.sol b/test/periphery/integration/merkle-lockup/ll/clawback/clawback.t.sol index 0256e4d6b..7253a379f 100644 --- a/test/periphery/integration/merkle-lockup/ll/clawback/clawback.t.sol +++ b/test/periphery/integration/merkle-lockup/ll/clawback/clawback.t.sol @@ -45,7 +45,7 @@ contract Clawback_Integration_Test is MerkleLockup_Integration_Test { function test_RevertGiven_CampaignNotExpired() external whenCallerAdmin afterFirstClaim postGracePeriod { vm.expectRevert( abi.encodeWithSelector( - Errors.SablierMerkleLockup_ClawbackNotAllowed.selector, + Errors.SablierMerkleBase_ClawbackNotAllowed.selector, getBlockTimestamp(), defaults.EXPIRATION(), defaults.FIRST_CLAIM_TIME() diff --git a/test/periphery/integration/merkle-lockup/ll/constructor/constructor.t.sol b/test/periphery/integration/merkle-lockup/ll/constructor/constructor.t.sol index 612adfadf..aa0a98868 100644 --- a/test/periphery/integration/merkle-lockup/ll/constructor/constructor.t.sol +++ b/test/periphery/integration/merkle-lockup/ll/constructor/constructor.t.sol @@ -34,7 +34,9 @@ contract Constructor_MerkleLL_Integration_Test is MerkleLockup_Integration_Test } function test_Constructor() external { - SablierMerkleLL constructedLL = new SablierMerkleLL(defaults.baseParams(), lockupLinear, defaults.durations()); + SablierMerkleLL constructedLL = new SablierMerkleLL( + defaults.baseParams(), lockupLinear, defaults.CANCELABLE(), defaults.TRANSFERABLE(), defaults.durations() + ); Vars memory vars; diff --git a/test/periphery/integration/merkle-lockup/lt/claim/claim.t.sol b/test/periphery/integration/merkle-lockup/lt/claim/claim.t.sol index 81aea9d28..a9310d2ef 100644 --- a/test/periphery/integration/merkle-lockup/lt/claim/claim.t.sol +++ b/test/periphery/integration/merkle-lockup/lt/claim/claim.t.sol @@ -7,7 +7,7 @@ import { ud2x18 } from "@prb/math/src/UD2x18.sol"; import { Lockup, LockupTranched } from "src/core/types/DataTypes.sol"; import { ISablierMerkleLT } from "src/periphery/interfaces/ISablierMerkleLT.sol"; import { Errors } from "src/periphery/libraries/Errors.sol"; -import { MerkleLockup, MerkleLT } from "src/periphery/types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "src/periphery/types/DataTypes.sol"; import { MerkleBuilder } from "test/utils/MerkleBuilder.sol"; import { Merkle } from "test/utils/Murky.sol"; @@ -27,7 +27,9 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { function test_RevertWhen_TotalPercentageLessThanOneHundred() external whenTotalPercentageNotOneHundred { // Create a MerkleLT campaign with a total percentage less than 100. - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); + bool cancelable = defaults.CANCELABLE(); + bool transferable = defaults.TRANSFERABLE(); uint256 aggregateAmount = defaults.AGGREGATE_AMOUNT(); uint256 recipientCount = defaults.RECIPIENT_COUNT(); @@ -38,8 +40,14 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint64 totalPercentage = tranchesWithPercentages[0].unlockPercentage.unwrap() + tranchesWithPercentages[1].unlockPercentage.unwrap(); - merkleLT = merkleLockupFactory.createMerkleLT( - baseParams, lockupTranched, tranchesWithPercentages, aggregateAmount, recipientCount + merkleLT = merkleFactory.createMerkleLT( + baseParams, + lockupTranched, + cancelable, + transferable, + tranchesWithPercentages, + aggregateAmount, + recipientCount ); // Claim an airstream. @@ -54,7 +62,9 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { function test_RevertWhen_TotalPercentageGreaterThanOneHundred() external whenTotalPercentageNotOneHundred { // Create a MerkleLT campaign with a total percentage less than 100. - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); + bool cancelable = defaults.CANCELABLE(); + bool transferable = defaults.TRANSFERABLE(); uint256 aggregateAmount = defaults.AGGREGATE_AMOUNT(); uint256 recipientCount = defaults.RECIPIENT_COUNT(); @@ -65,8 +75,14 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint64 totalPercentage = tranchesWithPercentages[0].unlockPercentage.unwrap() + tranchesWithPercentages[1].unlockPercentage.unwrap(); - merkleLT = merkleLockupFactory.createMerkleLT( - baseParams, lockupTranched, tranchesWithPercentages, aggregateAmount, recipientCount + merkleLT = merkleFactory.createMerkleLT( + baseParams, + lockupTranched, + cancelable, + transferable, + tranchesWithPercentages, + aggregateAmount, + recipientCount ); // Claim an airstream. @@ -88,9 +104,7 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint256 warpTime = expiration + 1 seconds; bytes32[] memory merkleProof; vm.warp({ newTimestamp: warpTime }); - vm.expectRevert( - abi.encodeWithSelector(Errors.SablierMerkleLockup_CampaignExpired.selector, warpTime, expiration) - ); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_CampaignExpired.selector, warpTime, expiration)); merkleLT.claim({ index: 1, recipient: users.recipient1, amount: 1, merkleProof: merkleProof }); } @@ -103,7 +117,7 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint256 index1 = defaults.INDEX1(); uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_StreamClaimed.selector, index1)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_StreamClaimed.selector, index1)); merkleLT.claim(index1, users.recipient1, amount, merkleProof); } @@ -125,7 +139,7 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint256 invalidIndex = 1337; uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLT.claim(invalidIndex, users.recipient1, amount, merkleProof); } @@ -140,7 +154,7 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { address invalidRecipient = address(1337); uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLT.claim(index1, invalidRecipient, amount, merkleProof); } @@ -154,7 +168,7 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint256 index1 = defaults.INDEX1(); uint128 invalidAmount = 1337; bytes32[] memory merkleProof = defaults.index1Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLT.claim(index1, users.recipient1, invalidAmount, merkleProof); } @@ -168,7 +182,7 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { uint256 index1 = defaults.INDEX1(); uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory invalidMerkleProof = defaults.index2Proof(); - vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleLockup_InvalidProof.selector)); + vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_InvalidProof.selector)); merkleLT.claim(index1, users.recipient1, amount, invalidMerkleProof); } @@ -200,13 +214,15 @@ contract Claim_Integration_Test is Merkle, MerkleLockup_Integration_Test { bytes32[] memory proof = getProof(leaves.toBytes32(), pos); /// Declare the constructor params. - MerkleLockup.ConstructorParams memory baseParams = defaults.baseParams(); + MerkleBase.ConstructorParams memory baseParams = defaults.baseParams(); baseParams.merkleRoot = getRoot(leaves.toBytes32()); // Deploy a test MerkleLT contract. - ISablierMerkleLT testMerkleLT = merkleLockupFactory.createMerkleLT( + ISablierMerkleLT testMerkleLT = merkleFactory.createMerkleLT( baseParams, lockupTranched, + defaults.CANCELABLE(), + defaults.TRANSFERABLE(), defaults.tranchesWithPercentages(), defaults.AGGREGATE_AMOUNT(), defaults.RECIPIENT_COUNT() diff --git a/test/periphery/integration/merkle-lockup/lt/clawback/clawback.t.sol b/test/periphery/integration/merkle-lockup/lt/clawback/clawback.t.sol index 23ee08233..376a6b864 100644 --- a/test/periphery/integration/merkle-lockup/lt/clawback/clawback.t.sol +++ b/test/periphery/integration/merkle-lockup/lt/clawback/clawback.t.sol @@ -44,7 +44,7 @@ contract Clawback_Integration_Test is MerkleLockup_Integration_Test { function test_RevertGiven_CampaignNotExpired() external whenCallerAdmin afterFirstClaim postGracePeriod { vm.expectRevert( abi.encodeWithSelector( - Errors.SablierMerkleLockup_ClawbackNotAllowed.selector, + Errors.SablierMerkleBase_ClawbackNotAllowed.selector, getBlockTimestamp(), defaults.EXPIRATION(), defaults.FIRST_CLAIM_TIME() diff --git a/test/periphery/integration/merkle-lockup/lt/constructor/constructor.t.sol b/test/periphery/integration/merkle-lockup/lt/constructor/constructor.t.sol index 5d7ca85cb..dd7758156 100644 --- a/test/periphery/integration/merkle-lockup/lt/constructor/constructor.t.sol +++ b/test/periphery/integration/merkle-lockup/lt/constructor/constructor.t.sol @@ -36,8 +36,13 @@ contract Constructor_MerkleLT_Integration_Test is MerkleLockup_Integration_Test } function test_Constructor() external { - SablierMerkleLT constructedLT = - new SablierMerkleLT(defaults.baseParams(), lockupTranched, defaults.tranchesWithPercentages()); + SablierMerkleLT constructedLT = new SablierMerkleLT( + defaults.baseParams(), + lockupTranched, + defaults.CANCELABLE(), + defaults.TRANSFERABLE(), + defaults.tranchesWithPercentages() + ); Vars memory vars; diff --git a/test/utils/Defaults.sol b/test/utils/Defaults.sol index 5d569d589..e4651e209 100644 --- a/test/utils/Defaults.sol +++ b/test/utils/Defaults.sol @@ -7,7 +7,7 @@ import { ud2x18, uUNIT } from "@prb/math/src/UD2x18.sol"; import { UD60x18, ud, ZERO } from "@prb/math/src/UD60x18.sol"; import { Broker, Lockup, LockupDynamic, LockupLinear, LockupTranched } from "../../src/core/types/DataTypes.sol"; -import { BatchLockup, MerkleLockup, MerkleLT } from "../../src/periphery/types/DataTypes.sol"; +import { BatchLockup, MerkleBase, MerkleLT } from "../../src/periphery/types/DataTypes.sol"; import { ArrayBuilder } from "./ArrayBuilder.sol"; import { Constants } from "./Constants.sol"; @@ -443,7 +443,7 @@ contract Defaults is Constants, Merkle { MERKLE-LOCKUP //////////////////////////////////////////////////////////////////////////*/ - function baseParams() public view returns (MerkleLockup.ConstructorParams memory) { + function baseParams() public view returns (MerkleBase.ConstructorParams memory) { return baseParams(users.admin, asset, EXPIRATION, MERKLE_ROOT); } @@ -455,17 +455,15 @@ contract Defaults is Constants, Merkle { ) public pure - returns (MerkleLockup.ConstructorParams memory) + returns (MerkleBase.ConstructorParams memory) { - return MerkleLockup.ConstructorParams({ + return MerkleBase.ConstructorParams({ asset: asset_, - cancelable: CANCELABLE, expiration: expiration, initialAdmin: admin, ipfsCID: IPFS_CID, merkleRoot: merkleRoot, - name: NAME, - transferable: TRANSFERABLE + name: NAME }); } diff --git a/test/utils/DeployOptimized.sol b/test/utils/DeployOptimized.sol index 24fb0f293..37d1078ba 100644 --- a/test/utils/DeployOptimized.sol +++ b/test/utils/DeployOptimized.sol @@ -8,7 +8,7 @@ import { ISablierLockupLinear } from "../../src/core/interfaces/ISablierLockupLi import { ISablierLockupTranched } from "../../src/core/interfaces/ISablierLockupTranched.sol"; import { ISablierNFTDescriptor } from "../../src/core/interfaces/ISablierNFTDescriptor.sol"; import { ISablierBatchLockup } from "../../src/periphery/interfaces/ISablierBatchLockup.sol"; -import { ISablierMerkleLockupFactory } from "../../src/periphery/interfaces/ISablierMerkleLockupFactory.sol"; +import { ISablierMerkleFactory } from "../../src/periphery/interfaces/ISablierMerkleFactory.sol"; abstract contract DeployOptimized is StdCheats { /*////////////////////////////////////////////////////////////////////////// @@ -104,19 +104,17 @@ abstract contract DeployOptimized is StdCheats { return ISablierBatchLockup(deployCode("out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json")); } - /// @dev Deploys {SablierMerkleLockupFactory} from an optimized source compiled with `--via-ir`. - function deployOptimizedMerkleLockupFactory() internal returns (ISablierMerkleLockupFactory) { - return ISablierMerkleLockupFactory( - deployCode("out-optimized/SablierMerkleLockupFactory.sol/SablierMerkleLockupFactory.json") - ); + /// @dev Deploys {SablierMerkleFactory} from an optimized source compiled with `--via-ir`. + function deployOptimizedMerkleFactory() internal returns (ISablierMerkleFactory) { + return ISablierMerkleFactory(deployCode("out-optimized/SablierMerkleFactory.sol/SablierMerkleFactory.json")); } /// @notice Deploys all Periphery contracts from an optimized source in the following order: /// /// 1. {SablierBatchLockup} - /// 2. {SablierMerkleLockupFactory} - function deployOptimizedPeriphery() internal returns (ISablierBatchLockup, ISablierMerkleLockupFactory) { - return (deployOptimizedBatchLockup(), deployOptimizedMerkleLockupFactory()); + /// 2. {SablierMerkleFactory} + function deployOptimizedPeriphery() internal returns (ISablierBatchLockup, ISablierMerkleFactory) { + return (deployOptimizedBatchLockup(), deployOptimizedMerkleFactory()); } /*////////////////////////////////////////////////////////////////////////// @@ -130,7 +128,7 @@ abstract contract DeployOptimized is StdCheats { /// 3. {SablierLockupLinear} /// 4. {SablierLockupTranched} /// 5. {SablierBatchLockup} - /// 6. {SablierMerkleLockupFactory} + /// 6. {SablierMerkleFactory} function deployOptimizedProtocol( address initialAdmin, uint256 maxSegmentCount, @@ -143,11 +141,11 @@ abstract contract DeployOptimized is StdCheats { ISablierLockupTranched lockupTranched_, ISablierNFTDescriptor nftDescriptor_, ISablierBatchLockup batchLockup_, - ISablierMerkleLockupFactory merkleLockupFactory_ + ISablierMerkleFactory merkleFactory_ ) { (lockupDynamic_, lockupLinear_, lockupTranched_, nftDescriptor_) = deployOptimizedCore(initialAdmin, maxSegmentCount, maxTrancheCount); - (batchLockup_, merkleLockupFactory_) = deployOptimizedPeriphery(); + (batchLockup_, merkleFactory_) = deployOptimizedPeriphery(); } } diff --git a/test/utils/Events.sol b/test/utils/Events.sol index eb5239482..8e2f2f3fb 100644 --- a/test/utils/Events.sol +++ b/test/utils/Events.sol @@ -9,7 +9,7 @@ import { ISablierNFTDescriptor } from "../../src/core/interfaces/ISablierNFTDesc import { Lockup, LockupDynamic, LockupLinear, LockupTranched } from "../../src/core/types/DataTypes.sol"; import { ISablierMerkleLL } from "../../src/periphery/interfaces/ISablierMerkleLL.sol"; import { ISablierMerkleLT } from "../../src/periphery/interfaces/ISablierMerkleLT.sol"; -import { MerkleLockup, MerkleLT } from "../../src/periphery/types/DataTypes.sol"; +import { MerkleBase, MerkleLT } from "../../src/periphery/types/DataTypes.sol"; /// @notice Abstract contract containing all the events emitted by the protocol. abstract contract Events { @@ -106,8 +106,10 @@ abstract contract Events { event CreateMerkleLL( ISablierMerkleLL indexed merkleLL, - MerkleLockup.ConstructorParams baseParams, + MerkleBase.ConstructorParams baseParams, ISablierLockupLinear lockupLinear, + bool cancelable, + bool transferable, LockupLinear.Durations streamDurations, uint256 aggregateAmount, uint256 recipientCount @@ -115,8 +117,10 @@ abstract contract Events { event CreateMerkleLT( ISablierMerkleLT indexed merkleLT, - MerkleLockup.ConstructorParams baseParams, + MerkleBase.ConstructorParams baseParams, ISablierLockupTranched lockupTranched, + bool cancelable, + bool transferable, MerkleLT.TrancheWithPercentage[] tranchesWithPercentages, uint256 totalDuration, uint256 aggregateAmount, diff --git a/test/utils/Precompiles.t.sol b/test/utils/Precompiles.t.sol index 9d1793684..830efe9f7 100644 --- a/test/utils/Precompiles.t.sol +++ b/test/utils/Precompiles.t.sol @@ -9,7 +9,7 @@ import { ISablierLockupLinear } from "src/core/interfaces/ISablierLockupLinear.s import { ISablierLockupTranched } from "src/core/interfaces/ISablierLockupTranched.sol"; import { ISablierNFTDescriptor } from "src/core/interfaces/ISablierNFTDescriptor.sol"; import { ISablierBatchLockup } from "src/periphery/interfaces/ISablierBatchLockup.sol"; -import { ISablierMerkleLockupFactory } from "src/periphery/interfaces/ISablierMerkleLockupFactory.sol"; +import { ISablierMerkleFactory } from "src/periphery/interfaces/ISablierMerkleFactory.sol"; import { Base_Test } from "../Base.t.sol"; @@ -103,23 +103,21 @@ contract Precompiles_Test is Base_Test { assertEq(actualBatchLockup.code, expectedBatchLockup.code, "bytecodes mismatch"); } - function test_DeployMerkleLockupFactory() external onlyTestOptimizedProfile { - address actualFactory = address(precompiles.deployMerkleLockupFactory()); - address expectedFactory = address(deployOptimizedMerkleLockupFactory()); + function test_DeployMerkleFactory() external onlyTestOptimizedProfile { + address actualFactory = address(precompiles.deployMerkleFactory()); + address expectedFactory = address(deployOptimizedMerkleFactory()); assertEq(actualFactory.code, expectedFactory.code, "bytecodes mismatch"); } function test_DeployPeriphery() external onlyTestOptimizedProfile { - (ISablierBatchLockup actualBatchLockup, ISablierMerkleLockupFactory actualMerkleLockupFactory) = + (ISablierBatchLockup actualBatchLockup, ISablierMerkleFactory actualMerkleFactory) = precompiles.deployPeriphery(); - (ISablierBatchLockup expectedBatchLockup, ISablierMerkleLockupFactory expectedMerkleLockupFactory) = + (ISablierBatchLockup expectedBatchLockup, ISablierMerkleFactory expectedMerkleFactory) = deployOptimizedPeriphery(); assertEq(address(actualBatchLockup).code, address(expectedBatchLockup).code, "bytecodes mismatch"); - assertEq( - address(actualMerkleLockupFactory).code, address(expectedMerkleLockupFactory).code, "bytecodes mismatch" - ); + assertEq(address(actualMerkleFactory).code, address(expectedMerkleFactory).code, "bytecodes mismatch"); } /*//////////////////////////////////////////////////////////////////////////