{"matchId":"46819469","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2026-08-25T18:20:24Z","creationBytecode":{"onchainBytecode":"0x60a03461010b57601f6108e938819003918201601f19168301916001600160401b0383118484101761010f57808492604094855283398101031261010b57610052602061004b83610123565b9201610123565b6001600160a01b039091169081156100f857600180546001600160a01b03199081169091555f80549182168417815560405193916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36001600160a01b038116156100e9576080526107b1908161013882396080518181816102b901528181610483015261060e0152f35b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361010b5756fe6080806040526004361015610012575f80fd5b5f3560e01c908163150b7a02146105ad57508063292d5732146104195780634a4fbeec146103dc5780635bb478081461033f578063715018a614610320578063732e78e4146102e8578063791b98bc146102a457806379ba5097146102245780638da5cb5b146101fd578063b8a0d7ab146101b4578063c45a01551461018c578063e30c397814610164578063f2fde38b146100f25763fa22143d146100b6575f80fd5b346100ee5760203660031901126100ee576001600160a01b036100d761065a565b165f526003602052602060405f2054604051908152f35b5f80fd5b346100ee5760203660031901126100ee5761010b61065a565b610113610768565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b346100ee575f3660031901126100ee576001546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee576002546040516001600160a01b039091168152602090f35b346100ee5760403660031901126100ee576101cd61065a565b6002546001600160a01b031633036101ee576101ec9060243590610686565b005b631966391b60e11b5f5260045ffd5b346100ee575f3660031901126100ee575f546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee57600154336001600160a01b03821603610291576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b346100ee575f3660031901126100ee576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ee5760203660031901126100ee576001600160a01b0361030961065a565b165f526004602052602060405f2054604051908152f35b346100ee575f3660031901126100ee576317d5c96560e11b5f5260045ffd5b346100ee5760203660031901126100ee5761035861065a565b610360610768565b600254906001600160a01b0382166103ce576001600160a01b03169081156103bf576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b346100ee5760203660031901126100ee576001600160a01b036103fd61065a565b165f526005602052602060ff60405f2054166040519015158152f35b346100ee5760403660031901126100ee5761043261065a565b60025460243591906001600160a01b031633036101ee576001600160a01b03165f8181526005602052604090205460ff1661059e576040516331a9108f60e11b8152600481018390526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610593575f91610527575b50306001600160a01b039091160361051857805f52600560205260405f20600160ff19825416179055805f5260036020528160405f20557f2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb545f80a3005b6335a4e4a560e11b5f5260045ffd5b905060203d60201161058c575b601f8101601f1916820167ffffffffffffffff811183821017610578576020918391604052810103126100ee57516001600160a01b03811681036100ee57836104bb565b634e487b7160e01b5f52604160045260245ffd5b503d610534565b6040513d5f823e3d90fd5b637f184cdb60e11b5f5260045ffd5b346100ee5760803660031901126100ee576105c661065a565b506105cf610670565b5060643567ffffffffffffffff81116100ee57366023820112156100ee57806004013567ffffffffffffffff81116100ee57369101602401116100ee577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361064b57630a85bd0160e11b8152602090f35b63041fb8cb60e31b5f5260045ffd5b600435906001600160a01b03821682036100ee57565b602435906001600160a01b03821682036100ee57565b6001600160a01b03169081156103bf578015610764576040516323b872dd60e01b5f5233600452306024528160445260205f60648180875af160015f5114811615610745575b816040525f6060521561073257825f52600460205260405f209081549280840180941161071e577faf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c74093602093558152a2565b634e487b7160e01b5f52601160045260245ffd5b82635274afe760e01b5f5260045260245ffd5b600181151661075b57833b15153d1516166106cc565b503d5f823e3d90fd5b5050565b5f546001600160a01b031633036102915756fea264697066735822122097e6c3a361a2a63bbab4eabde586fffcae2cdcf67e11d7bc3025a53e1288fb2a64736f6c63430008230033000000000000000000000000fdde5a1e3cdf791da71e49f817d70c7ced72cc3600000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa7","recompiledBytecode":"0x60a03461010b57601f6108e938819003918201601f19168301916001600160401b0383118484101761010f57808492604094855283398101031261010b57610052602061004b83610123565b9201610123565b6001600160a01b039091169081156100f857600180546001600160a01b03199081169091555f80549182168417815560405193916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36001600160a01b038116156100e9576080526107b1908161013882396080518181816102b901528181610483015261060e0152f35b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361010b5756fe6080806040526004361015610012575f80fd5b5f3560e01c908163150b7a02146105ad57508063292d5732146104195780634a4fbeec146103dc5780635bb478081461033f578063715018a614610320578063732e78e4146102e8578063791b98bc146102a457806379ba5097146102245780638da5cb5b146101fd578063b8a0d7ab146101b4578063c45a01551461018c578063e30c397814610164578063f2fde38b146100f25763fa22143d146100b6575f80fd5b346100ee5760203660031901126100ee576001600160a01b036100d761065a565b165f526003602052602060405f2054604051908152f35b5f80fd5b346100ee5760203660031901126100ee5761010b61065a565b610113610768565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b346100ee575f3660031901126100ee576001546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee576002546040516001600160a01b039091168152602090f35b346100ee5760403660031901126100ee576101cd61065a565b6002546001600160a01b031633036101ee576101ec9060243590610686565b005b631966391b60e11b5f5260045ffd5b346100ee575f3660031901126100ee575f546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee57600154336001600160a01b03821603610291576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b346100ee575f3660031901126100ee576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ee5760203660031901126100ee576001600160a01b0361030961065a565b165f526004602052602060405f2054604051908152f35b346100ee575f3660031901126100ee576317d5c96560e11b5f5260045ffd5b346100ee5760203660031901126100ee5761035861065a565b610360610768565b600254906001600160a01b0382166103ce576001600160a01b03169081156103bf576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b346100ee5760203660031901126100ee576001600160a01b036103fd61065a565b165f526005602052602060ff60405f2054166040519015158152f35b346100ee5760403660031901126100ee5761043261065a565b60025460243591906001600160a01b031633036101ee576001600160a01b03165f8181526005602052604090205460ff1661059e576040516331a9108f60e11b8152600481018390526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610593575f91610527575b50306001600160a01b039091160361051857805f52600560205260405f20600160ff19825416179055805f5260036020528160405f20557f2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb545f80a3005b6335a4e4a560e11b5f5260045ffd5b905060203d60201161058c575b601f8101601f1916820167ffffffffffffffff811183821017610578576020918391604052810103126100ee57516001600160a01b03811681036100ee57836104bb565b634e487b7160e01b5f52604160045260245ffd5b503d610534565b6040513d5f823e3d90fd5b637f184cdb60e11b5f5260045ffd5b346100ee5760803660031901126100ee576105c661065a565b506105cf610670565b5060643567ffffffffffffffff81116100ee57366023820112156100ee57806004013567ffffffffffffffff81116100ee57369101602401116100ee577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361064b57630a85bd0160e11b8152602090f35b63041fb8cb60e31b5f5260045ffd5b600435906001600160a01b03821682036100ee57565b602435906001600160a01b03821682036100ee57565b6001600160a01b03169081156103bf578015610764576040516323b872dd60e01b5f5233600452306024528160445260205f60648180875af160015f5114811615610745575b816040525f6060521561073257825f52600460205260405f209081549280840180941161071e577faf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c74093602093558152a2565b634e487b7160e01b5f52601160045260245ffd5b82635274afe760e01b5f5260045260245ffd5b600181151661075b57833b15153d1516166106cc565b503d5f823e3d90fd5b5050565b5f546001600160a01b031633036102915756fea26469706673582212208d481560aa76d293360090b6d4964b83df3c7cc1923fe964d4b7bc4b2e2011ca64736f6c634300081a0033","sourceMap":"1034:4100:12:-:0;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;-1:-1:-1;;;;;1034:4100:12;;;;1273:26:0;;1269:95;;1034:4100:12;;;-1:-1:-1;;;;;;1034:4100:12;;;;;;-1:-1:-1;1034:4100:12;;;;;;;;;;;;;-1:-1:-1;;;;;1034:4100:12;;3052:40:0;;-1:-1:-1;3052:40:0;-1:-1:-1;;;;;1034:4100:12;;2105:30;2101:56;;2167:34;;1034:4100;;;;;;2167:34;1034:4100;;;;;;;;;;;;;;;;2101:56;2144:13;;;-1:-1:-1;2144:13:12;;-1:-1:-1;2144:13:12;1269:95:0;1322:31;;;-1:-1:-1;1322:31:0;-1:-1:-1;1322:31:0;1034:4100:12;;-1:-1:-1;1322:31:0;1034:4100:12;-1:-1:-1;1034:4100:12;;;;;;-1:-1:-1;1034:4100:12;;;;;-1:-1:-1;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;:::o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa26469706673582212208d481560aa76d293360090b6d4964b83df3c7cc1923fe964d4b7bc4b2e2011ca64736f6c634300081a0033","offset":2228}},"transformations":[{"id":"1","type":"replace","offset":2228,"reason":"cborAuxdata"},{"type":"insert","offset":2281,"reason":"constructorArguments"}],"transformationValues":{"cborAuxdata":{"1":"0xa264697066735822122097e6c3a361a2a63bbab4eabde586fffcae2cdcf67e11d7bc3025a53e1288fb2a64736f6c63430008230033"},"constructorArguments":"0x000000000000000000000000fdde5a1e3cdf791da71e49f817d70c7ced72cc3600000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa7"}},"runtimeBytecode":{"onchainBytecode":"0x6080806040526004361015610012575f80fd5b5f3560e01c908163150b7a02146105ad57508063292d5732146104195780634a4fbeec146103dc5780635bb478081461033f578063715018a614610320578063732e78e4146102e8578063791b98bc146102a457806379ba5097146102245780638da5cb5b146101fd578063b8a0d7ab146101b4578063c45a01551461018c578063e30c397814610164578063f2fde38b146100f25763fa22143d146100b6575f80fd5b346100ee5760203660031901126100ee576001600160a01b036100d761065a565b165f526003602052602060405f2054604051908152f35b5f80fd5b346100ee5760203660031901126100ee5761010b61065a565b610113610768565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b346100ee575f3660031901126100ee576001546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee576002546040516001600160a01b039091168152602090f35b346100ee5760403660031901126100ee576101cd61065a565b6002546001600160a01b031633036101ee576101ec9060243590610686565b005b631966391b60e11b5f5260045ffd5b346100ee575f3660031901126100ee575f546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee57600154336001600160a01b03821603610291576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b346100ee575f3660031901126100ee576040517f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa76001600160a01b03168152602090f35b346100ee5760203660031901126100ee576001600160a01b0361030961065a565b165f526004602052602060405f2054604051908152f35b346100ee575f3660031901126100ee576317d5c96560e11b5f5260045ffd5b346100ee5760203660031901126100ee5761035861065a565b610360610768565b600254906001600160a01b0382166103ce576001600160a01b03169081156103bf576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b346100ee5760203660031901126100ee576001600160a01b036103fd61065a565b165f526005602052602060ff60405f2054166040519015158152f35b346100ee5760403660031901126100ee5761043261065a565b60025460243591906001600160a01b031633036101ee576001600160a01b03165f8181526005602052604090205460ff1661059e576040516331a9108f60e11b8152600481018390526020816024817f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa76001600160a01b03165afa908115610593575f91610527575b50306001600160a01b039091160361051857805f52600560205260405f20600160ff19825416179055805f5260036020528160405f20557f2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb545f80a3005b6335a4e4a560e11b5f5260045ffd5b905060203d60201161058c575b601f8101601f1916820167ffffffffffffffff811183821017610578576020918391604052810103126100ee57516001600160a01b03811681036100ee57836104bb565b634e487b7160e01b5f52604160045260245ffd5b503d610534565b6040513d5f823e3d90fd5b637f184cdb60e11b5f5260045ffd5b346100ee5760803660031901126100ee576105c661065a565b506105cf610670565b5060643567ffffffffffffffff81116100ee57366023820112156100ee57806004013567ffffffffffffffff81116100ee57369101602401116100ee577f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa76001600160a01b0316330361064b57630a85bd0160e11b8152602090f35b63041fb8cb60e31b5f5260045ffd5b600435906001600160a01b03821682036100ee57565b602435906001600160a01b03821682036100ee57565b6001600160a01b03169081156103bf578015610764576040516323b872dd60e01b5f5233600452306024528160445260205f60648180875af160015f5114811615610745575b816040525f6060521561073257825f52600460205260405f209081549280840180941161071e577faf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c74093602093558152a2565b634e487b7160e01b5f52601160045260245ffd5b82635274afe760e01b5f5260045260245ffd5b600181151661075b57833b15153d1516166106cc565b503d5f823e3d90fd5b5050565b5f546001600160a01b031633036102915756fea264697066735822122097e6c3a361a2a63bbab4eabde586fffcae2cdcf67e11d7bc3025a53e1288fb2a64736f6c63430008230033","recompiledBytecode":"0x6080806040526004361015610012575f80fd5b5f3560e01c908163150b7a02146105ad57508063292d5732146104195780634a4fbeec146103dc5780635bb478081461033f578063715018a614610320578063732e78e4146102e8578063791b98bc146102a457806379ba5097146102245780638da5cb5b146101fd578063b8a0d7ab146101b4578063c45a01551461018c578063e30c397814610164578063f2fde38b146100f25763fa22143d146100b6575f80fd5b346100ee5760203660031901126100ee576001600160a01b036100d761065a565b165f526003602052602060405f2054604051908152f35b5f80fd5b346100ee5760203660031901126100ee5761010b61065a565b610113610768565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b346100ee575f3660031901126100ee576001546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee576002546040516001600160a01b039091168152602090f35b346100ee5760403660031901126100ee576101cd61065a565b6002546001600160a01b031633036101ee576101ec9060243590610686565b005b631966391b60e11b5f5260045ffd5b346100ee575f3660031901126100ee575f546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee57600154336001600160a01b03821603610291576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b346100ee575f3660031901126100ee576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ee5760203660031901126100ee576001600160a01b0361030961065a565b165f526004602052602060405f2054604051908152f35b346100ee575f3660031901126100ee576317d5c96560e11b5f5260045ffd5b346100ee5760203660031901126100ee5761035861065a565b610360610768565b600254906001600160a01b0382166103ce576001600160a01b03169081156103bf576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b346100ee5760203660031901126100ee576001600160a01b036103fd61065a565b165f526005602052602060ff60405f2054166040519015158152f35b346100ee5760403660031901126100ee5761043261065a565b60025460243591906001600160a01b031633036101ee576001600160a01b03165f8181526005602052604090205460ff1661059e576040516331a9108f60e11b8152600481018390526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610593575f91610527575b50306001600160a01b039091160361051857805f52600560205260405f20600160ff19825416179055805f5260036020528160405f20557f2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb545f80a3005b6335a4e4a560e11b5f5260045ffd5b905060203d60201161058c575b601f8101601f1916820167ffffffffffffffff811183821017610578576020918391604052810103126100ee57516001600160a01b03811681036100ee57836104bb565b634e487b7160e01b5f52604160045260245ffd5b503d610534565b6040513d5f823e3d90fd5b637f184cdb60e11b5f5260045ffd5b346100ee5760803660031901126100ee576105c661065a565b506105cf610670565b5060643567ffffffffffffffff81116100ee57366023820112156100ee57806004013567ffffffffffffffff81116100ee57369101602401116100ee577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361064b57630a85bd0160e11b8152602090f35b63041fb8cb60e31b5f5260045ffd5b600435906001600160a01b03821682036100ee57565b602435906001600160a01b03821682036100ee57565b6001600160a01b03169081156103bf578015610764576040516323b872dd60e01b5f5233600452306024528160445260205f60648180875af160015f5114811615610745575b816040525f6060521561073257825f52600460205260405f209081549280840180941161071e577faf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c74093602093558152a2565b634e487b7160e01b5f52601160045260245ffd5b82635274afe760e01b5f5260045260245ffd5b600181151661075b57833b15153d1516166106cc565b503d5f823e3d90fd5b5050565b5f546001600160a01b031633036102915756fea26469706673582212208d481560aa76d293360090b6d4964b83df3c7cc1923fe964d4b7bc4b2e2011ca64736f6c634300081a0033","sourceMap":"1034:4100:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;:::i;:::-;;;;1619:64;1034:4100;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;1034:4100:12;;;;;;;;;;1738:24:1;1034:4100:12;;;1738:24:1;1034:4100:12;;;;;;;;;1777:43:1;1034:4100:12;1777:43:1;;1034:4100:12;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;1590:22;1034:4100;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;2265:7;1034:4100;-1:-1:-1;;;;;1034:4100:12;2251:10;:21;2247:46;;2303:1;1034:4100;;;2303:1;;:::i;:::-;1034:4100;2247:46;2281:12;;;1034:4100;2281:12;1034:4100;;2281:12;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;1311:13:1;1034:4100:12;735:10:10;-1:-1:-1;;;;;1034:4100:12;;2339:24:1;2335:96;;-1:-1:-1;;;;;;1034:4100:12;;;1311:13:1;1034:4100:12;;;;735:10:10;1034:4100:12;;;;;;;-1:-1:-1;;;;;1034:4100:12;;3052:40:0;;1034:4100:12;3052:40:0;1034:4100:12;2335:96:1;2386:34;;;1034:4100:12;2386:34:1;735:10:10;1034:4100:12;;;;2386:34:1;1034:4100:12;;;;;;-1:-1:-1;;1034:4100:12;;;;;;1544:40;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;2969:28;;;1034:4100;2969:28;1034:4100;;2969:28;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;2483:7:12;1034:4100;;-1:-1:-1;;;;;1034:4100:12;;2479:54;;-1:-1:-1;;;;;1034:4100:12;;2547:22;;2543:48;;-1:-1:-1;;;;;;1034:4100:12;;;2483:7;1034:4100;;;;;;2634:20;;1034:4100;;2634:20;1034:4100;2543:48;2578:13;;;1034:4100;2578:13;1034:4100;;2578:13;2479:54;2513:20;;;1034:4100;2513:20;1034:4100;;2513:20;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;:::i;:::-;;;;5111:7;1034:4100;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;2265:7;1034:4100;;;;;-1:-1:-1;;;;;1034:4100:12;2251:10;:21;2247:46;;-1:-1:-1;;;;;1034:4100:12;;;;;4158:7;1034:4100;;;;;;;;4154:50;;1034:4100;;-1:-1:-1;;;4218:41:12;;1034:4100;4218:41;;1034:4100;;;;;;;4226:15;-1:-1:-1;;;;;1034:4100:12;4218:41;;;;;;;1034:4100;4218:41;;;1034:4100;-1:-1:-1;4271:4:12;-1:-1:-1;;;;;1034:4100:12;;;4218:58;4214:88;;1034:4100;;;4158:7;1034:4100;;;;;;;;;;;;;;;;;4344:15;1034:4100;;;;;;;4391:30;1034:4100;4391:30;;1034:4100;4214:88;4285:17;;;1034:4100;4285:17;1034:4100;;4285:17;4218:41;;;1034:4100;4218:41;1034:4100;4218:41;;;;1034:4100;;;-1:-1:-1;;1034:4100:12;;;;;;;;;;;;;;;;;;4218:41;;1034:4100;;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;4218:41;;;1034:4100;;;;;;;;;;;;4218:41;;;;;;1034:4100;;;;;;;;;4154:50;4181:23;;;1034:4100;4181:23;1034:4100;;4181:23;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3710:15;-1:-1:-1;;;;;1034:4100:12;3696:10;:29;3692:62;;-1:-1:-1;;;1034:4100:12;;;;;3692:62;3734:20;;;1034:4100;3734:20;1034:4100;;3734:20;1034:4100;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;:::o;4599:338::-;-1:-1:-1;;;;;1034:4100:12;;4690:19;;4686:45;;4745:11;;4741:24;;11053:1148:8;;11014:28;;;4707:1:12;11053:1148:8;4805:10:12;11053:1148:8;;4825:4:12;11053:1148:8;;;;;;4707:1:12;11053:1148:8;;;;;;1880:4;4707:1:12;11053:1148:8;;;;;;;4599:338:12;11053:1148:8;;;4707:1:12;11053:1148:8;;1837:48;1833:126;;1034:4100:12;4707:1;1034:4100;11053:1148:8;;1034:4100:12;11053:1148:8;4707:1:12;1034:4100;;;;;;;;;;;;;4898:32;1034:4100;11053:1148:8;1034:4100:12;;;;4898:32;4599:338::o;1034:4100::-;;;;4707:1;1034:4100;;11053:1148:8;1034:4100:12;11053:1148:8;4707:1:12;1034:4100;1833:126:8;1908:40;;;;4707:1:12;1908:40:8;11053:1148;1034:4100:12;11053:1148:8;4707:1:12;1908:40:8;11053:1148;1880:4;11053:1148;;;;;;;;;;;;;;;;;;4707:1:12;11053:1148:8;;;;;4741:24:12;4758:7;;:::o;1796:162:0:-;1710:6;1034:4100:12;-1:-1:-1;;;;;1034:4100:12;735:10:10;1855:23:0;1851:101;;1796:162::o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa26469706673582212208d481560aa76d293360090b6d4964b83df3c7cc1923fe964d4b7bc4b2e2011ca64736f6c634300081a0033","offset":1916}},"immutableReferences":{"1121":[{"start":697,"length":32},{"start":1155,"length":32},{"start":1550,"length":32}]},"transformations":[{"id":"1121","type":"replace","offset":697,"reason":"immutable"},{"id":"1121","type":"replace","offset":1155,"reason":"immutable"},{"id":"1121","type":"replace","offset":1550,"reason":"immutable"},{"id":"1","type":"replace","offset":1916,"reason":"cborAuxdata"}],"transformationValues":{"immutables":{"1121":"0x00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa7"},"cborAuxdata":{"1":"0xa264697066735822122097e6c3a361a2a63bbab4eabde586fffcae2cdcf67e11d7bc3025a53e1288fb2a64736f6c63430008230033"}}},"deployment":{"transactionHash":"0x7b2f3e9dee1d150521161ee9fd071659aec18af8f07e5f63c6c53b28c315f47b","blockNumber":"26841845","transactionIndex":"10","deployer":"0xFdDE5a1E3cDF791Da71E49F817D70C7ceD72CC36"},"sources":{"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     *\n     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20Metadata} from \"../token/ERC20/extensions/IERC20Metadata.sol\";\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\nimport {IERC20Metadata} from \"../../../interfaces/IERC20Metadata.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /// @dev Attempts to fetch the token decimals. A return value of false indicates that the attempt failed in some way.\n    function tryGetDecimals(IERC20 token) internal view returns (bool success, uint8 decimals) {\n        bytes4 selector = IERC20Metadata.decimals.selector;\n        assembly (\"memory-safe\") {\n            mstore(0x00, selector)\n            success := staticcall(gas(), token, 0x00, 4, 0x00, 0x20)\n            success := and(and(success, gt(returndatasize(), 0x1f)), lt(mload(0x00), 0x100))\n            decimals := mul(success, mload(0x00))\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/IERC721.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC-721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC-721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\n     *   {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"src/v2/RobinFunFiV2LaunchLocker.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC721ReceiverLike} from \"./interfaces/ILaunchpadV2.sol\";\n\n/**\n * @title RobinFunFiV2LaunchLocker\n * @notice Permanently holds the graduated Uniswap V4 position NFT for every\n * robinfun v2 launch. Unlike v1's locker, there is no `collectFees()` here: fee\n * collection and distribution belong entirely to RobinFunFiV2MemeHook and\n * RobinFunFiV2FeeEscrow, since a V4 position accrues fees inside the singleton\n * PoolManager rather than on the NFT itself. This contract exposes no\n * withdrawal or arbitrary-call function, so locked liquidity can never be\n * removed by an administrator.\n */\ncontract RobinFunFiV2LaunchLocker is Ownable2Step, IERC721ReceiverLike {\n    using SafeERC20 for IERC20;\n\n    error NotFactory();\n    error AlreadyInitialized();\n    error ZeroAddress();\n    error PositionAlreadyLocked();\n    error PositionNotHeld();\n    error NotPositionManager();\n    error OwnershipCannotBeRenounced();\n\n    event FactorySet(address factory);\n    event PositionLocked(address indexed token, uint256 indexed tokenId);\n    event TokenSupplyLocked(address indexed token, uint256 amount);\n\n    address public immutable positionManager;\n    address public factory;\n\n    mapping(address token => uint256 tokenId) public lockedPositions;\n    mapping(address token => uint256 amount) public lockedTokenSupply;\n    mapping(address token => bool locked) private _locked;\n\n    /**\n     * @param initialOwner Administrative owner; only used to wire the factory once.\n     * @param positionManager_ The canonical Uniswap V4 PositionManager for this chain.\n     */\n    constructor(address initialOwner, address positionManager_) Ownable(initialOwner) {\n        if (positionManager_ == address(0)) revert ZeroAddress();\n        positionManager = positionManager_;\n    }\n\n    modifier onlyFactory() {\n        if (msg.sender != factory) revert NotFactory();\n        _;\n    }\n\n    /**\n     * @notice One-time wiring of the v2 factory, set after both are deployed.\n     */\n    function setFactory(address factory_) external onlyOwner {\n        if (factory != address(0)) revert AlreadyInitialized();\n        if (factory_ == address(0)) revert ZeroAddress();\n        factory = factory_;\n        emit FactorySet(factory_);\n    }\n\n    /**\n     * @notice Permanently disabled. Ownership here exists only to perform the\n     * one-time factory wiring, and renouncing before that wiring would leave\n     * the locker unable to ever accept a graduated position.\n     */\n    function renounceOwnership() public pure override {\n        revert OwnershipCannotBeRenounced();\n    }\n\n    /**\n     * @notice Rejects safe transfers of anything but a canonical position NFT.\n     * @dev Not part of the graduation path. Graduation names this locker as\n     * the `MINT_POSITION` owner, and the PositionManager mints with a plain\n     * `_mint`, which fires no receiver callback. Custody is established by\n     * the `ownerOf` check in `lockPosition` instead. This exists so the\n     * locker still behaves correctly under an explicit `safeTransferFrom`,\n     * and so such a transfer can only ever originate from the canonical\n     * PositionManager.\n     */\n    function onERC721Received(address, address, uint256, bytes calldata) external view returns (bytes4) {\n        if (msg.sender != positionManager) revert NotPositionManager();\n        return IERC721ReceiverLike.onERC721Received.selector;\n    }\n\n    /**\n     * @notice Registers and verifies permanent custody of a graduated position.\n     * @dev Called once per launch by the factory, immediately after minting\n     * the full-range position directly to this locker's address.\n     */\n    function lockPosition(address token, uint256 tokenId) external onlyFactory {\n        if (_locked[token]) revert PositionAlreadyLocked();\n        if (IERC721(positionManager).ownerOf(tokenId) != address(this)) revert PositionNotHeld();\n\n        _locked[token] = true;\n        lockedPositions[token] = tokenId;\n        emit PositionLocked(token, tokenId);\n    }\n\n    /**\n     * @notice Permanently locks the virtual-reserve token remainder that\n     * cannot enter the graduated pool without lowering its opening price.\n     */\n    function lockTokenSupply(address token, uint256 amount) external onlyFactory {\n        if (token == address(0)) revert ZeroAddress();\n        if (amount == 0) return;\n        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n        lockedTokenSupply[token] += amount;\n        emit TokenSupplyLocked(token, amount);\n    }\n\n    /**\n     * @notice Returns whether a launch's position has been locked here.\n     */\n    function isLocked(address token) external view returns (bool) {\n        return _locked[token];\n    }\n}\n"},"src/v2/interfaces/ILaunchpadV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n/**\n * @notice Shared robinfun v2 interfaces: fee escrow, fee policy, and the launch\n * factory/curve records. Uniswap V4 core and periphery types are imported\n * directly from the vendored packages by the contracts that need them,\n * rather than re-declared here.\n */\n\n/**\n * @notice Claimable balance ledger shared by every v2 bonding curve and the\n * meme hook. Native ETH crediting is permissionless (callers attach the ETH\n * they are crediting). Token crediting requires the caller to hold the\n * tokens themselves, pulled via `transferFrom`, so it is equally safe to\n * leave open. Token support exists for launches whose deployer-chosen\n * pairToken is a non-native ERC-20: those curves trade and credit in that\n * asset from the first trade through to graduation.\n */\ninterface IRobinFunFiV2FeeEscrow {\n    function credit(address recipient) external payable;\n    function creditToken(address recipient, address token, uint256 amount) external;\n    function claim() external returns (uint256 amount);\n    function claim(uint256 amount) external returns (uint256);\n    function claimToken(address token) external returns (uint256 amount);\n    function claimToken(address token, uint256 amount) external returns (uint256);\n    function balanceOf(address recipient) external view returns (uint256);\n    function balanceOfToken(address recipient, address token) external view returns (uint256);\n}\n\n/**\n * @notice Fee terms frozen for one launch when its curve is created and its\n * graduated pool is registered. Global hook configuration only governs\n * launches created after a later policy update.\n */\nstruct FeePolicySnapshot {\n    address protocolFeeRecipient;\n    uint16 protocolFeeShareBps;\n    uint16 buybackBurnBps;\n    uint16 hookFeeBps;\n    uint16 maxInternalPriceImpactBps;\n}\n\n/**\n * @notice Protocol-owned fee policy read by every bonding curve and by the\n * meme hook. The current policy is snapshotted at launch, while the live\n * sweep operator remains rotatable for operational liveness.\n */\ninterface IRobinFunFiV2FeePolicy {\n    function protocolFeeShareBps() external view returns (uint256);\n    function buybackBurnBps() external view returns (uint256);\n    function protocolFeeRecipient() external view returns (address);\n    function feeEscrow() external view returns (IRobinFunFiV2FeeEscrow);\n    // Ceiling on how much a single internal buyback conversion is allowed\n    // to move the pool's own price, read by the meme hook's real internal\n    // swaps and by the bonding curve's pre-graduation buyback pricing so\n    // both phases apply the same conservative bound.\n    function maxInternalPriceImpactBps() external view returns (uint256);\n    function feeSweepOperator() external view returns (address);\n    function currentFeePolicy() external view returns (FeePolicySnapshot memory);\n}\n\n/**\n * @notice Anti-snipe tax terms each bonding curve snapshots from the factory\n * when it initializes, inside its own launch transaction. Implemented by\n * RobinFunFiV2LaunchFactory as owner-mutable settings that govern launches from\n * the moment they change; a curve already trading keeps the terms it\n * launched under, so a factory retune can never reprice an open launch\n * window. `snipeTaxStartBps` is the tax charged in the launch second, in\n * basis points of a buy's quote leg, decaying exponentially to zero across\n * `snipeTaxSeconds`. A zero starting tax disables the mechanism.\n */\ninterface IRobinFunFiV2SnipeTax {\n    function snipeTaxStartBps() external view returns (uint256);\n    function snipeTaxSeconds() external view returns (uint256);\n}\n\n/**\n * @notice Minimal ERC-721 receiver signature used by RobinFunFiV2LaunchLocker to\n * accept the graduated Uniswap V4 position NFT.\n */\ninterface IERC721ReceiverLike {\n    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data)\n        external\n        returns (bytes4);\n}\n\n/**\n * @notice Graduation proceeds in two phases so the slippage-sensitive step\n * is never bundled with the automatic, threshold-crossing trigger:\n * - NotGraduated: still trading on the bonding curve.\n * - Swept: the curve has been drained (fees swept, trading halted, ETH and\n *   the remaining token supply pulled into the factory); still needs a V4\n *   pool.\n * - PoolCreated: the V4 pool exists, its full-range position is locked, and\n *   the meme hook is registered for it.\n * - Rescued: the swept reserves were released manually because the launch's\n *   quote asset stopped being able to deliver an exact transfer, which no\n *   retry of the seed step could ever satisfy. Terminal, like PoolCreated.\n */\nenum GraduationPhase {\n    NotGraduated,\n    Swept,\n    PoolCreated,\n    Rescued\n}\n\n/**\n * @notice Record kept by RobinFunFiV2LaunchFactory for every launch, readable by\n * the locker and by off-chain indexers.\n */\ninterface IRobinFunFiV2LaunchFactory {\n    struct LaunchedToken {\n        address token;\n        address curve;\n        address deployer;\n        address creatorFeeRecipient;\n        address pairToken;\n        uint256 graduationThreshold;\n        // Snapshotted from the launch config at launch time, so a later\n        // config edit can never change the pool a token graduates into.\n        uint24 poolFee;\n        int24 tickSpacing;\n        // Creator-chosen at launch, capped by the protocol's maxCreatorTaxBps\n        // at the time of launch; an additional trade fee charged the same\n        // way the base fee is, paid entirely to the creator.\n        uint16 creatorTaxBps;\n        bool buybackEnabled;\n        GraduationPhase phase;\n        uint256 sweptQuote;\n        uint256 sweptTokens;\n        uint256 sweptAt;\n        bool exists;\n    }\n\n    function getLaunchedToken(address token) external view returns (LaunchedToken memory);\n}\n\n/**\n * @notice Narrow surface the factory needs from a bonding curve to trigger\n * graduation once the ETH threshold has been crossed.\n */\ninterface IRobinFunFiV2BondingCurve {\n    function token() external view returns (address);\n    function pairToken() external view returns (address);\n    function graduationThreshold() external view returns (uint256);\n    function graduated() external view returns (bool);\n    function quoteReserve() external view returns (uint256);\n    function realQuoteReserve() external view returns (uint256);\n    function tokenReserve() external view returns (uint256);\n    function readyToGraduate() external view returns (bool);\n    function sweepFees(uint256 minBuybackTokensOut) external;\n    function graduate(address recipient) external returns (uint256 ethOut, uint256 tokenOut);\n}\n"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.26+commit.8a97fa7a","compilerSettings":{"viaIR":true,"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"libraries":{},"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun","remappings":["@openzeppelin/=lib/openzeppelin-contracts/","forge-std/=lib/forge-std/src/","@uniswap/v4-core/=lib/v4-core/","@uniswap/v4-periphery/=lib/v4-periphery/","@uniswap/v4-hooks-public/=lib/v4-hooks-public/","permit2/=lib/v4-periphery/lib/permit2/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/","v4-core/=lib/v4-core/src/","v4-hooks-public/=lib/v4-hooks-public/src/","v4-periphery/=lib/v4-periphery/src/"]},"name":"RobinFunFiV2LaunchLocker","fullyQualifiedName":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"},{"name":"positionManager_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"AlreadyInitialized","type":"error","inputs":[]},{"name":"NotFactory","type":"error","inputs":[]},{"name":"NotPositionManager","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"OwnershipCannotBeRenounced","type":"error","inputs":[]},{"name":"PositionAlreadyLocked","type":"error","inputs":[]},{"name":"PositionNotHeld","type":"error","inputs":[]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"FactorySet","type":"event","inputs":[{"name":"factory","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferStarted","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"PositionLocked","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"TokenSupplyLocked","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isLocked","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"lockPosition","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"lockTokenSupply","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"lockedPositions","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"lockedTokenSupply","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"onERC721Received","type":"function","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"positionManager","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"pure"},{"name":"setFactory","type":"function","inputs":[{"name":"factory_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"metadata":{"compiler":{"version":"0.8.26+commit.8a97fa7a"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"address","name":"positionManager_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"NotFactory","type":"error"},{"inputs":[],"name":"NotPositionManager","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnershipCannotBeRenounced","type":"error"},{"inputs":[],"name":"PositionAlreadyLocked","type":"error"},{"inputs":[],"name":"PositionNotHeld","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"factory","type":"address"}],"name":"FactorySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"PositionLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenSupplyLocked","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"lockPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"lockTokenSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"lockedPositions","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"lockedTokenSupply","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"factory_","type":"address"}],"name":"setFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}]},"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"constructor":{"params":{"initialOwner":"Administrative owner; only used to wire the factory once.","positionManager_":"The canonical Uniswap V4 PositionManager for this chain."}},"lockPosition(address,uint256)":{"details":"Called once per launch by the factory, immediately after minting the full-range position directly to this locker's address."},"onERC721Received(address,address,uint256,bytes)":{"details":"Not part of the graduation path. Graduation names this locker as the `MINT_POSITION` owner, and the PositionManager mints with a plain `_mint`, which fires no receiver callback. Custody is established by the `ownerOf` check in `lockPosition` instead. This exists so the locker still behaves correctly under an explicit `safeTransferFrom`, and so such a transfer can only ever originate from the canonical PositionManager."},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."}},"title":"RobinFunFiV2LaunchLocker","version":1},"userdoc":{"kind":"user","methods":{"isLocked(address)":{"notice":"Returns whether a launch's position has been locked here."},"lockPosition(address,uint256)":{"notice":"Registers and verifies permanent custody of a graduated position."},"lockTokenSupply(address,uint256)":{"notice":"Permanently locks the virtual-reserve token remainder that cannot enter the graduated pool without lowering its opening price."},"onERC721Received(address,address,uint256,bytes)":{"notice":"Rejects safe transfers of anything but a canonical position NFT."},"renounceOwnership()":{"notice":"Permanently disabled. Ownership here exists only to perform the one-time factory wiring, and renouncing before that wiring would leave the locker unable to ever accept a graduated position."},"setFactory(address)":{"notice":"One-time wiring of the v2 factory, set after both are deployed."}},"notice":"Permanently holds the graduated Uniswap V4 position NFT for every robinfun v2 launch. Unlike v1's locker, there is no `collectFees()` here: fee collection and distribution belong entirely to RobinFunFiV2MemeHook and RobinFunFiV2FeeEscrow, since a V4 position accrues fees inside the singleton PoolManager rather than on the NFT itself. This contract exposes no withdrawal or arbitrary-call function, so locked liquidity can never be removed by an administrator.","version":1}},"settings":{"compilationTarget":{"src/v2/RobinFunFiV2LaunchLocker.sol":"RobinFunFiV2LaunchLocker"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[":@openzeppelin/=lib/openzeppelin-contracts/",":@uniswap/v4-core/=lib/v4-core/",":@uniswap/v4-hooks-public/=lib/v4-hooks-public/",":@uniswap/v4-periphery/=lib/v4-periphery/",":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",":forge-std/=lib/forge-std/src/",":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",":openzeppelin-contracts/=lib/openzeppelin-contracts/",":permit2/=lib/v4-periphery/lib/permit2/",":v4-core/=lib/v4-core/src/",":v4-hooks-public/=lib/v4-hooks-public/src/",":v4-periphery/=lib/v4-periphery/src/"],"viaIR":true},"sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb","license":"MIT","urls":["bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6","dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a"]},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c","license":"MIT","urls":["bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0","dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek"]},"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"keccak256":"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d","license":"MIT","urls":["bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100","dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d"]},"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"keccak256":"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc","license":"MIT","urls":["bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037","dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ"]},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44","license":"MIT","urls":["bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d","dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF"]},"lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol":{"keccak256":"0xd735962e3d6660884153ba8a972b5f100dde4c482f2ff1c525ba7fdefb154cbd","license":"MIT","urls":["bzz-raw://5a264d17b093f585844b0d977e9f60555b8c8d6513b304fde863cdf652a0d336","dweb:/ipfs/QmWXfaJisjVnrjTUjZGryZpMob9wKivvtbodLS3PTc1ttq"]},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2","license":"MIT","urls":["bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303","dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV"]},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f","license":"MIT","urls":["bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e","dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR"]},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x377051c0c17a28038c32f58d76a42817eb3b24f2b4c6a2e788a9544e856d738d","license":"MIT","urls":["bzz-raw://c5365fead4a20b84662284c97c07d707c67f5bc9e07b371980aba8c3c6e83661","dweb:/ipfs/QmYrYoLPEADtXoCu9ZBnwkXdNB9D9FPHuhS9pWaQW4nYx5"]},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f","license":"MIT","urls":["bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3","dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9"]},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","license":"MIT","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"]},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c","license":"MIT","urls":["bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617","dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u"]},"src/v2/RobinFunFiV2LaunchLocker.sol":{"keccak256":"0xc3c9e1d54b2f3db6763fbb0346375d22204cdd7b1a4ccfcb5bf9601c808ad362","license":"MIT","urls":["bzz-raw://353f3d385b9e1b21d49549133be54be1f0fae25b33e9b8b39b94b9fce87a21e4","dweb:/ipfs/QmcxyTHfd9S6F1uvHYUtnuPxEhXLBt92KbHg6zK6qXWMKC"]},"src/v2/interfaces/ILaunchpadV2.sol":{"keccak256":"0x634dd0fcdee89702ed8a5e5a3f57e2ef3bc9192e047aff7b417c5eb0387b70c2","license":"MIT","urls":["bzz-raw://3a08548eb0032a445f8da2637b297121a62ec398ed7591126b3d37adc19263c8","dweb:/ipfs/Qmd8bJtPEZPjVjCMq46EyZCteh3yEd7AzD8adKivDkFGWG"]}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_uint256)":{"key":"t_address","label":"mapping(address => uint256)","value":"t_uint256","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":8,"label":"_owner","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"1","type":"t_address","astId":156,"label":"_pendingOwner","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"2","type":"t_address","astId":1123,"label":"factory","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"3","type":"t_mapping(t_address,t_uint256)","astId":1127,"label":"lockedPositions","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"4","type":"t_mapping(t_address,t_uint256)","astId":1131,"label":"lockedTokenSupply","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"5","type":"t_mapping(t_address,t_bool)","astId":1135,"label":"_locked","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"}]},"transientStorageLayout":null,"userdoc":{"kind":"user","notice":"Permanently holds the graduated Uniswap V4 position NFT for every robinfun v2 launch. Unlike v1's locker, there is no `collectFees()` here: fee collection and distribution belong entirely to RobinFunFiV2MemeHook and RobinFunFiV2FeeEscrow, since a V4 position accrues fees inside the singleton PoolManager rather than on the NFT itself. This contract exposes no withdrawal or arbitrary-call function, so locked liquidity can never be removed by an administrator.","methods":{"isLocked(address)":{"notice":"Returns whether a launch's position has been locked here."},"renounceOwnership()":{"notice":"Permanently disabled. Ownership here exists only to perform the one-time factory wiring, and renouncing before that wiring would leave the locker unable to ever accept a graduated position."},"setFactory(address)":{"notice":"One-time wiring of the v2 factory, set after both are deployed."},"lockPosition(address,uint256)":{"notice":"Registers and verifies permanent custody of a graduated position."},"lockTokenSupply(address,uint256)":{"notice":"Permanently locks the virtual-reserve token remainder that cannot enter the graduated pool without lowering its opening price."},"onERC721Received(address,address,uint256,bytes)":{"notice":"Rejects safe transfers of anything but a canonical position NFT."}},"version":1},"devdoc":{"kind":"dev","title":"RobinFunFiV2LaunchLocker","errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}]},"methods":{"owner()":{"details":"Returns the address of the current owner."},"constructor":{"params":{"initialOwner":"Administrative owner; only used to wire the factory once.","positionManager_":"The canonical Uniswap V4 PositionManager for this chain."}},"pendingOwner()":{"details":"Returns the address of the pending owner."},"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."},"lockPosition(address,uint256)":{"details":"Called once per launch by the factory, immediately after minting the full-range position directly to this locker's address."},"onERC721Received(address,address,uint256,bytes)":{"details":"Not part of the graduation path. Graduation names this locker as the `MINT_POSITION` owner, and the PositionManager mints with a plain `_mint`, which fires no receiver callback. Custody is established by the `ownerOf` check in `lockPosition` instead. This exists so the locker still behaves correctly under an explicit `safeTransferFrom`, and so such a transfer can only ever originate from the canonical PositionManager."}},"version":1},"sourceIds":{"src/v2/interfaces/ILaunchpadV2.sol":{"id":13},"src/v2/RobinFunFiV2LaunchLocker.sol":{"id":12},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"id":10},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"id":0},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"id":4},"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"id":3},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"id":6},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"id":1},"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"id":2},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"id":9},"lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol":{"id":5},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"id":8},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"id":11},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":7}},"additionalInput":null,"stdJsonInput":{"sources":{"src/v2/interfaces/ILaunchpadV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n/**\n * @notice Shared robinfun v2 interfaces: fee escrow, fee policy, and the launch\n * factory/curve records. Uniswap V4 core and periphery types are imported\n * directly from the vendored packages by the contracts that need them,\n * rather than re-declared here.\n */\n\n/**\n * @notice Claimable balance ledger shared by every v2 bonding curve and the\n * meme hook. Native ETH crediting is permissionless (callers attach the ETH\n * they are crediting). Token crediting requires the caller to hold the\n * tokens themselves, pulled via `transferFrom`, so it is equally safe to\n * leave open. Token support exists for launches whose deployer-chosen\n * pairToken is a non-native ERC-20: those curves trade and credit in that\n * asset from the first trade through to graduation.\n */\ninterface IRobinFunFiV2FeeEscrow {\n    function credit(address recipient) external payable;\n    function creditToken(address recipient, address token, uint256 amount) external;\n    function claim() external returns (uint256 amount);\n    function claim(uint256 amount) external returns (uint256);\n    function claimToken(address token) external returns (uint256 amount);\n    function claimToken(address token, uint256 amount) external returns (uint256);\n    function balanceOf(address recipient) external view returns (uint256);\n    function balanceOfToken(address recipient, address token) external view returns (uint256);\n}\n\n/**\n * @notice Fee terms frozen for one launch when its curve is created and its\n * graduated pool is registered. Global hook configuration only governs\n * launches created after a later policy update.\n */\nstruct FeePolicySnapshot {\n    address protocolFeeRecipient;\n    uint16 protocolFeeShareBps;\n    uint16 buybackBurnBps;\n    uint16 hookFeeBps;\n    uint16 maxInternalPriceImpactBps;\n}\n\n/**\n * @notice Protocol-owned fee policy read by every bonding curve and by the\n * meme hook. The current policy is snapshotted at launch, while the live\n * sweep operator remains rotatable for operational liveness.\n */\ninterface IRobinFunFiV2FeePolicy {\n    function protocolFeeShareBps() external view returns (uint256);\n    function buybackBurnBps() external view returns (uint256);\n    function protocolFeeRecipient() external view returns (address);\n    function feeEscrow() external view returns (IRobinFunFiV2FeeEscrow);\n    // Ceiling on how much a single internal buyback conversion is allowed\n    // to move the pool's own price, read by the meme hook's real internal\n    // swaps and by the bonding curve's pre-graduation buyback pricing so\n    // both phases apply the same conservative bound.\n    function maxInternalPriceImpactBps() external view returns (uint256);\n    function feeSweepOperator() external view returns (address);\n    function currentFeePolicy() external view returns (FeePolicySnapshot memory);\n}\n\n/**\n * @notice Anti-snipe tax terms each bonding curve snapshots from the factory\n * when it initializes, inside its own launch transaction. Implemented by\n * RobinFunFiV2LaunchFactory as owner-mutable settings that govern launches from\n * the moment they change; a curve already trading keeps the terms it\n * launched under, so a factory retune can never reprice an open launch\n * window. `snipeTaxStartBps` is the tax charged in the launch second, in\n * basis points of a buy's quote leg, decaying exponentially to zero across\n * `snipeTaxSeconds`. A zero starting tax disables the mechanism.\n */\ninterface IRobinFunFiV2SnipeTax {\n    function snipeTaxStartBps() external view returns (uint256);\n    function snipeTaxSeconds() external view returns (uint256);\n}\n\n/**\n * @notice Minimal ERC-721 receiver signature used by RobinFunFiV2LaunchLocker to\n * accept the graduated Uniswap V4 position NFT.\n */\ninterface IERC721ReceiverLike {\n    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data)\n        external\n        returns (bytes4);\n}\n\n/**\n * @notice Graduation proceeds in two phases so the slippage-sensitive step\n * is never bundled with the automatic, threshold-crossing trigger:\n * - NotGraduated: still trading on the bonding curve.\n * - Swept: the curve has been drained (fees swept, trading halted, ETH and\n *   the remaining token supply pulled into the factory); still needs a V4\n *   pool.\n * - PoolCreated: the V4 pool exists, its full-range position is locked, and\n *   the meme hook is registered for it.\n * - Rescued: the swept reserves were released manually because the launch's\n *   quote asset stopped being able to deliver an exact transfer, which no\n *   retry of the seed step could ever satisfy. Terminal, like PoolCreated.\n */\nenum GraduationPhase {\n    NotGraduated,\n    Swept,\n    PoolCreated,\n    Rescued\n}\n\n/**\n * @notice Record kept by RobinFunFiV2LaunchFactory for every launch, readable by\n * the locker and by off-chain indexers.\n */\ninterface IRobinFunFiV2LaunchFactory {\n    struct LaunchedToken {\n        address token;\n        address curve;\n        address deployer;\n        address creatorFeeRecipient;\n        address pairToken;\n        uint256 graduationThreshold;\n        // Snapshotted from the launch config at launch time, so a later\n        // config edit can never change the pool a token graduates into.\n        uint24 poolFee;\n        int24 tickSpacing;\n        // Creator-chosen at launch, capped by the protocol's maxCreatorTaxBps\n        // at the time of launch; an additional trade fee charged the same\n        // way the base fee is, paid entirely to the creator.\n        uint16 creatorTaxBps;\n        bool buybackEnabled;\n        GraduationPhase phase;\n        uint256 sweptQuote;\n        uint256 sweptTokens;\n        uint256 sweptAt;\n        bool exists;\n    }\n\n    function getLaunchedToken(address token) external view returns (LaunchedToken memory);\n}\n\n/**\n * @notice Narrow surface the factory needs from a bonding curve to trigger\n * graduation once the ETH threshold has been crossed.\n */\ninterface IRobinFunFiV2BondingCurve {\n    function token() external view returns (address);\n    function pairToken() external view returns (address);\n    function graduationThreshold() external view returns (uint256);\n    function graduated() external view returns (bool);\n    function quoteReserve() external view returns (uint256);\n    function realQuoteReserve() external view returns (uint256);\n    function tokenReserve() external view returns (uint256);\n    function readyToGraduate() external view returns (bool);\n    function sweepFees(uint256 minBuybackTokensOut) external;\n    function graduate(address recipient) external returns (uint256 ethOut, uint256 tokenOut);\n}\n"},"src/v2/RobinFunFiV2LaunchLocker.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC721ReceiverLike} from \"./interfaces/ILaunchpadV2.sol\";\n\n/**\n * @title RobinFunFiV2LaunchLocker\n * @notice Permanently holds the graduated Uniswap V4 position NFT for every\n * robinfun v2 launch. Unlike v1's locker, there is no `collectFees()` here: fee\n * collection and distribution belong entirely to RobinFunFiV2MemeHook and\n * RobinFunFiV2FeeEscrow, since a V4 position accrues fees inside the singleton\n * PoolManager rather than on the NFT itself. This contract exposes no\n * withdrawal or arbitrary-call function, so locked liquidity can never be\n * removed by an administrator.\n */\ncontract RobinFunFiV2LaunchLocker is Ownable2Step, IERC721ReceiverLike {\n    using SafeERC20 for IERC20;\n\n    error NotFactory();\n    error AlreadyInitialized();\n    error ZeroAddress();\n    error PositionAlreadyLocked();\n    error PositionNotHeld();\n    error NotPositionManager();\n    error OwnershipCannotBeRenounced();\n\n    event FactorySet(address factory);\n    event PositionLocked(address indexed token, uint256 indexed tokenId);\n    event TokenSupplyLocked(address indexed token, uint256 amount);\n\n    address public immutable positionManager;\n    address public factory;\n\n    mapping(address token => uint256 tokenId) public lockedPositions;\n    mapping(address token => uint256 amount) public lockedTokenSupply;\n    mapping(address token => bool locked) private _locked;\n\n    /**\n     * @param initialOwner Administrative owner; only used to wire the factory once.\n     * @param positionManager_ The canonical Uniswap V4 PositionManager for this chain.\n     */\n    constructor(address initialOwner, address positionManager_) Ownable(initialOwner) {\n        if (positionManager_ == address(0)) revert ZeroAddress();\n        positionManager = positionManager_;\n    }\n\n    modifier onlyFactory() {\n        if (msg.sender != factory) revert NotFactory();\n        _;\n    }\n\n    /**\n     * @notice One-time wiring of the v2 factory, set after both are deployed.\n     */\n    function setFactory(address factory_) external onlyOwner {\n        if (factory != address(0)) revert AlreadyInitialized();\n        if (factory_ == address(0)) revert ZeroAddress();\n        factory = factory_;\n        emit FactorySet(factory_);\n    }\n\n    /**\n     * @notice Permanently disabled. Ownership here exists only to perform the\n     * one-time factory wiring, and renouncing before that wiring would leave\n     * the locker unable to ever accept a graduated position.\n     */\n    function renounceOwnership() public pure override {\n        revert OwnershipCannotBeRenounced();\n    }\n\n    /**\n     * @notice Rejects safe transfers of anything but a canonical position NFT.\n     * @dev Not part of the graduation path. Graduation names this locker as\n     * the `MINT_POSITION` owner, and the PositionManager mints with a plain\n     * `_mint`, which fires no receiver callback. Custody is established by\n     * the `ownerOf` check in `lockPosition` instead. This exists so the\n     * locker still behaves correctly under an explicit `safeTransferFrom`,\n     * and so such a transfer can only ever originate from the canonical\n     * PositionManager.\n     */\n    function onERC721Received(address, address, uint256, bytes calldata) external view returns (bytes4) {\n        if (msg.sender != positionManager) revert NotPositionManager();\n        return IERC721ReceiverLike.onERC721Received.selector;\n    }\n\n    /**\n     * @notice Registers and verifies permanent custody of a graduated position.\n     * @dev Called once per launch by the factory, immediately after minting\n     * the full-range position directly to this locker's address.\n     */\n    function lockPosition(address token, uint256 tokenId) external onlyFactory {\n        if (_locked[token]) revert PositionAlreadyLocked();\n        if (IERC721(positionManager).ownerOf(tokenId) != address(this)) revert PositionNotHeld();\n\n        _locked[token] = true;\n        lockedPositions[token] = tokenId;\n        emit PositionLocked(token, tokenId);\n    }\n\n    /**\n     * @notice Permanently locks the virtual-reserve token remainder that\n     * cannot enter the graduated pool without lowering its opening price.\n     */\n    function lockTokenSupply(address token, uint256 amount) external onlyFactory {\n        if (token == address(0)) revert ZeroAddress();\n        if (amount == 0) return;\n        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n        lockedTokenSupply[token] += amount;\n        emit TokenSupplyLocked(token, amount);\n    }\n\n    /**\n     * @notice Returns whether a launch's position has been locked here.\n     */\n    function isLocked(address token) external view returns (bool) {\n        return _locked[token];\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     *\n     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/IERC721.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC-721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC-721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\n     *   {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20Metadata} from \"../token/ERC20/extensions/IERC20Metadata.sol\";\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\nimport {IERC20Metadata} from \"../../../interfaces/IERC20Metadata.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /// @dev Attempts to fetch the token decimals. A return value of false indicates that the attempt failed in some way.\n    function tryGetDecimals(IERC20 token) internal view returns (bool success, uint8 decimals) {\n        bytes4 selector = IERC20Metadata.decimals.selector;\n        assembly (\"memory-safe\") {\n            mstore(0x00, selector)\n            success := staticcall(gas(), token, 0x00, 4, 0x00, 0x20)\n            success := and(and(success, gt(returndatasize(), 0x1f)), lt(mload(0x00), 0x100))\n            decimals := mul(success, mload(0x00))\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"}},"language":"Solidity","settings":{"viaIR":true,"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"libraries":{},"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun","remappings":["@openzeppelin/=lib/openzeppelin-contracts/","forge-std/=lib/forge-std/src/","@uniswap/v4-core/=lib/v4-core/","@uniswap/v4-periphery/=lib/v4-periphery/","@uniswap/v4-hooks-public/=lib/v4-hooks-public/","permit2/=lib/v4-periphery/lib/permit2/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/","v4-core/=lib/v4-core/src/","v4-hooks-public/=lib/v4-hooks-public/src/","v4-periphery/=lib/v4-periphery/src/"]}},"stdJsonOutput":{"sources":{"src/v2/interfaces/ILaunchpadV2.sol":{"id":13},"src/v2/RobinFunFiV2LaunchLocker.sol":{"id":12},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"id":10},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"id":0},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"id":4},"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"id":3},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"id":6},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"id":1},"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"id":2},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"id":9},"lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol":{"id":5},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"id":8},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"id":11},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":7}},"contracts":{"src/v2/RobinFunFiV2LaunchLocker.sol":{"RobinFunFiV2LaunchLocker":{"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"},{"name":"positionManager_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"AlreadyInitialized","type":"error","inputs":[]},{"name":"NotFactory","type":"error","inputs":[]},{"name":"NotPositionManager","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"OwnershipCannotBeRenounced","type":"error","inputs":[]},{"name":"PositionAlreadyLocked","type":"error","inputs":[]},{"name":"PositionNotHeld","type":"error","inputs":[]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"FactorySet","type":"event","inputs":[{"name":"factory","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferStarted","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"PositionLocked","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"TokenSupplyLocked","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isLocked","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"lockPosition","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"lockTokenSupply","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"lockedPositions","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"lockedTokenSupply","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"onERC721Received","type":"function","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"positionManager","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"pure"},{"name":"setFactory","type":"function","inputs":[{"name":"factory_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"metadata":"{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"positionManager_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotFactory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotPositionManager\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnershipCannotBeRenounced\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PositionAlreadyLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PositionNotHeld\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"}],\"name\":\"FactorySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"PositionLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenSupplyLocked\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"lockPosition\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"lockTokenSupply\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"lockedPositions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"lockedTokenSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"positionManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"factory_\",\"type\":\"address\"}],\"name\":\"setFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC-20 token failed.\"}]},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"params\":{\"initialOwner\":\"Administrative owner; only used to wire the factory once.\",\"positionManager_\":\"The canonical Uniswap V4 PositionManager for this chain.\"}},\"lockPosition(address,uint256)\":{\"details\":\"Called once per launch by the factory, immediately after minting the full-range position directly to this locker's address.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Not part of the graduation path. Graduation names this locker as the `MINT_POSITION` owner, and the PositionManager mints with a plain `_mint`, which fires no receiver callback. Custody is established by the `ownerOf` check in `lockPosition` instead. This exists so the locker still behaves correctly under an explicit `safeTransferFrom`, and so such a transfer can only ever originate from the canonical PositionManager.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\"}},\"title\":\"RobinFunFiV2LaunchLocker\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"isLocked(address)\":{\"notice\":\"Returns whether a launch's position has been locked here.\"},\"lockPosition(address,uint256)\":{\"notice\":\"Registers and verifies permanent custody of a graduated position.\"},\"lockTokenSupply(address,uint256)\":{\"notice\":\"Permanently locks the virtual-reserve token remainder that cannot enter the graduated pool without lowering its opening price.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Rejects safe transfers of anything but a canonical position NFT.\"},\"renounceOwnership()\":{\"notice\":\"Permanently disabled. Ownership here exists only to perform the one-time factory wiring, and renouncing before that wiring would leave the locker unable to ever accept a graduated position.\"},\"setFactory(address)\":{\"notice\":\"One-time wiring of the v2 factory, set after both are deployed.\"}},\"notice\":\"Permanently holds the graduated Uniswap V4 position NFT for every robinfun v2 launch. Unlike v1's locker, there is no `collectFees()` here: fee collection and distribution belong entirely to RobinFunFiV2MemeHook and RobinFunFiV2FeeEscrow, since a V4 position accrues fees inside the singleton PoolManager rather than on the NFT itself. This contract exposes no withdrawal or arbitrary-call function, so locked liquidity can never be removed by an administrator.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/v2/RobinFunFiV2LaunchLocker.sol\":\"RobinFunFiV2LaunchLocker\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/=lib/openzeppelin-contracts/\",\":@uniswap/v4-core/=lib/v4-core/\",\":@uniswap/v4-hooks-public/=lib/v4-hooks-public/\",\":@uniswap/v4-periphery/=lib/v4-periphery/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":permit2/=lib/v4-periphery/lib/permit2/\",\":v4-core/=lib/v4-core/src/\",\":v4-hooks-public/=lib/v4-hooks-public/src/\",\":v4-periphery/=lib/v4-periphery/src/\"],\"viaIR\":true},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6\",\"dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0\",\"dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol\":{\"keccak256\":\"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100\",\"dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol\":{\"keccak256\":\"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037\",\"dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d\",\"dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol\":{\"keccak256\":\"0xd735962e3d6660884153ba8a972b5f100dde4c482f2ff1c525ba7fdefb154cbd\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a264d17b093f585844b0d977e9f60555b8c8d6513b304fde863cdf652a0d336\",\"dweb:/ipfs/QmWXfaJisjVnrjTUjZGryZpMob9wKivvtbodLS3PTc1ttq\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303\",\"dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e\",\"dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x377051c0c17a28038c32f58d76a42817eb3b24f2b4c6a2e788a9544e856d738d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c5365fead4a20b84662284c97c07d707c67f5bc9e07b371980aba8c3c6e83661\",\"dweb:/ipfs/QmYrYoLPEADtXoCu9ZBnwkXdNB9D9FPHuhS9pWaQW4nYx5\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\",\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12\",\"dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"]},\"src/v2/RobinFunFiV2LaunchLocker.sol\":{\"keccak256\":\"0xc3c9e1d54b2f3db6763fbb0346375d22204cdd7b1a4ccfcb5bf9601c808ad362\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://353f3d385b9e1b21d49549133be54be1f0fae25b33e9b8b39b94b9fce87a21e4\",\"dweb:/ipfs/QmcxyTHfd9S6F1uvHYUtnuPxEhXLBt92KbHg6zK6qXWMKC\"]},\"src/v2/interfaces/ILaunchpadV2.sol\":{\"keccak256\":\"0x634dd0fcdee89702ed8a5e5a3f57e2ef3bc9192e047aff7b417c5eb0387b70c2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3a08548eb0032a445f8da2637b297121a62ec398ed7591126b3d37adc19263c8\",\"dweb:/ipfs/Qmd8bJtPEZPjVjCMq46EyZCteh3yEd7AzD8adKivDkFGWG\"]}},\"version\":1}","userdoc":{"kind":"user","notice":"Permanently holds the graduated Uniswap V4 position NFT for every robinfun v2 launch. Unlike v1's locker, there is no `collectFees()` here: fee collection and distribution belong entirely to RobinFunFiV2MemeHook and RobinFunFiV2FeeEscrow, since a V4 position accrues fees inside the singleton PoolManager rather than on the NFT itself. This contract exposes no withdrawal or arbitrary-call function, so locked liquidity can never be removed by an administrator.","methods":{"isLocked(address)":{"notice":"Returns whether a launch's position has been locked here."},"renounceOwnership()":{"notice":"Permanently disabled. Ownership here exists only to perform the one-time factory wiring, and renouncing before that wiring would leave the locker unable to ever accept a graduated position."},"setFactory(address)":{"notice":"One-time wiring of the v2 factory, set after both are deployed."},"lockPosition(address,uint256)":{"notice":"Registers and verifies permanent custody of a graduated position."},"lockTokenSupply(address,uint256)":{"notice":"Permanently locks the virtual-reserve token remainder that cannot enter the graduated pool without lowering its opening price."},"onERC721Received(address,address,uint256,bytes)":{"notice":"Rejects safe transfers of anything but a canonical position NFT."}},"version":1},"devdoc":{"kind":"dev","title":"RobinFunFiV2LaunchLocker","errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}]},"methods":{"owner()":{"details":"Returns the address of the current owner."},"constructor":{"params":{"initialOwner":"Administrative owner; only used to wire the factory once.","positionManager_":"The canonical Uniswap V4 PositionManager for this chain."}},"pendingOwner()":{"details":"Returns the address of the pending owner."},"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."},"lockPosition(address,uint256)":{"details":"Called once per launch by the factory, immediately after minting the full-range position directly to this locker's address."},"onERC721Received(address,address,uint256,bytes)":{"details":"Not part of the graduation path. Graduation names this locker as the `MINT_POSITION` owner, and the PositionManager mints with a plain `_mint`, which fires no receiver callback. Custody is established by the `ownerOf` check in `lockPosition` instead. This exists so the locker still behaves correctly under an explicit `safeTransferFrom`, and so such a transfer can only ever originate from the canonical PositionManager."}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_uint256)":{"key":"t_address","label":"mapping(address => uint256)","value":"t_uint256","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":8,"label":"_owner","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"1","type":"t_address","astId":156,"label":"_pendingOwner","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"2","type":"t_address","astId":1123,"label":"factory","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"3","type":"t_mapping(t_address,t_uint256)","astId":1127,"label":"lockedPositions","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"4","type":"t_mapping(t_address,t_uint256)","astId":1131,"label":"lockedTokenSupply","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"},{"slot":"5","type":"t_mapping(t_address,t_bool)","astId":1135,"label":"_locked","offset":0,"contract":"src/v2/RobinFunFiV2LaunchLocker.sol:RobinFunFiV2LaunchLocker"}]},"transientStorageLayout":null,"evm":{"bytecode":{"object":"60a03461010b57601f6108e938819003918201601f19168301916001600160401b0383118484101761010f57808492604094855283398101031261010b57610052602061004b83610123565b9201610123565b6001600160a01b039091169081156100f857600180546001600160a01b03199081169091555f80549182168417815560405193916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36001600160a01b038116156100e9576080526107b1908161013882396080518181816102b901528181610483015261060e0152f35b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361010b5756fe6080806040526004361015610012575f80fd5b5f3560e01c908163150b7a02146105ad57508063292d5732146104195780634a4fbeec146103dc5780635bb478081461033f578063715018a614610320578063732e78e4146102e8578063791b98bc146102a457806379ba5097146102245780638da5cb5b146101fd578063b8a0d7ab146101b4578063c45a01551461018c578063e30c397814610164578063f2fde38b146100f25763fa22143d146100b6575f80fd5b346100ee5760203660031901126100ee576001600160a01b036100d761065a565b165f526003602052602060405f2054604051908152f35b5f80fd5b346100ee5760203660031901126100ee5761010b61065a565b610113610768565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b346100ee575f3660031901126100ee576001546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee576002546040516001600160a01b039091168152602090f35b346100ee5760403660031901126100ee576101cd61065a565b6002546001600160a01b031633036101ee576101ec9060243590610686565b005b631966391b60e11b5f5260045ffd5b346100ee575f3660031901126100ee575f546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee57600154336001600160a01b03821603610291576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b346100ee575f3660031901126100ee576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ee5760203660031901126100ee576001600160a01b0361030961065a565b165f526004602052602060405f2054604051908152f35b346100ee575f3660031901126100ee576317d5c96560e11b5f5260045ffd5b346100ee5760203660031901126100ee5761035861065a565b610360610768565b600254906001600160a01b0382166103ce576001600160a01b03169081156103bf576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b346100ee5760203660031901126100ee576001600160a01b036103fd61065a565b165f526005602052602060ff60405f2054166040519015158152f35b346100ee5760403660031901126100ee5761043261065a565b60025460243591906001600160a01b031633036101ee576001600160a01b03165f8181526005602052604090205460ff1661059e576040516331a9108f60e11b8152600481018390526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610593575f91610527575b50306001600160a01b039091160361051857805f52600560205260405f20600160ff19825416179055805f5260036020528160405f20557f2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb545f80a3005b6335a4e4a560e11b5f5260045ffd5b905060203d60201161058c575b601f8101601f1916820167ffffffffffffffff811183821017610578576020918391604052810103126100ee57516001600160a01b03811681036100ee57836104bb565b634e487b7160e01b5f52604160045260245ffd5b503d610534565b6040513d5f823e3d90fd5b637f184cdb60e11b5f5260045ffd5b346100ee5760803660031901126100ee576105c661065a565b506105cf610670565b5060643567ffffffffffffffff81116100ee57366023820112156100ee57806004013567ffffffffffffffff81116100ee57369101602401116100ee577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361064b57630a85bd0160e11b8152602090f35b63041fb8cb60e31b5f5260045ffd5b600435906001600160a01b03821682036100ee57565b602435906001600160a01b03821682036100ee57565b6001600160a01b03169081156103bf578015610764576040516323b872dd60e01b5f5233600452306024528160445260205f60648180875af160015f5114811615610745575b816040525f6060521561073257825f52600460205260405f209081549280840180941161071e577faf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c74093602093558152a2565b634e487b7160e01b5f52601160045260245ffd5b82635274afe760e01b5f5260045260245ffd5b600181151661075b57833b15153d1516166106cc565b503d5f823e3d90fd5b5050565b5f546001600160a01b031633036102915756fea26469706673582212208d481560aa76d293360090b6d4964b83df3c7cc1923fe964d4b7bc4b2e2011ca64736f6c634300081a0033","sourceMap":"1034:4100:12:-:0;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;-1:-1:-1;;;;;1034:4100:12;;;;1273:26:0;;1269:95;;1034:4100:12;;;-1:-1:-1;;;;;;1034:4100:12;;;;;;-1:-1:-1;1034:4100:12;;;;;;;;;;;;;-1:-1:-1;;;;;1034:4100:12;;3052:40:0;;-1:-1:-1;3052:40:0;-1:-1:-1;;;;;1034:4100:12;;2105:30;2101:56;;2167:34;;1034:4100;;;;;;2167:34;1034:4100;;;;;;;;;;;;;;;;2101:56;2144:13;;;-1:-1:-1;2144:13:12;;-1:-1:-1;2144:13:12;1269:95:0;1322:31;;;-1:-1:-1;1322:31:0;-1:-1:-1;1322:31:0;1034:4100:12;;-1:-1:-1;1322:31:0;1034:4100:12;-1:-1:-1;1034:4100:12;;;;;;-1:-1:-1;1034:4100:12;;;;;-1:-1:-1;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;:::o","linkReferences":{}},"deployedBytecode":{"object":"6080806040526004361015610012575f80fd5b5f3560e01c908163150b7a02146105ad57508063292d5732146104195780634a4fbeec146103dc5780635bb478081461033f578063715018a614610320578063732e78e4146102e8578063791b98bc146102a457806379ba5097146102245780638da5cb5b146101fd578063b8a0d7ab146101b4578063c45a01551461018c578063e30c397814610164578063f2fde38b146100f25763fa22143d146100b6575f80fd5b346100ee5760203660031901126100ee576001600160a01b036100d761065a565b165f526003602052602060405f2054604051908152f35b5f80fd5b346100ee5760203660031901126100ee5761010b61065a565b610113610768565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b346100ee575f3660031901126100ee576001546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee576002546040516001600160a01b039091168152602090f35b346100ee5760403660031901126100ee576101cd61065a565b6002546001600160a01b031633036101ee576101ec9060243590610686565b005b631966391b60e11b5f5260045ffd5b346100ee575f3660031901126100ee575f546040516001600160a01b039091168152602090f35b346100ee575f3660031901126100ee57600154336001600160a01b03821603610291576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b346100ee575f3660031901126100ee576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ee5760203660031901126100ee576001600160a01b0361030961065a565b165f526004602052602060405f2054604051908152f35b346100ee575f3660031901126100ee576317d5c96560e11b5f5260045ffd5b346100ee5760203660031901126100ee5761035861065a565b610360610768565b600254906001600160a01b0382166103ce576001600160a01b03169081156103bf576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b346100ee5760203660031901126100ee576001600160a01b036103fd61065a565b165f526005602052602060ff60405f2054166040519015158152f35b346100ee5760403660031901126100ee5761043261065a565b60025460243591906001600160a01b031633036101ee576001600160a01b03165f8181526005602052604090205460ff1661059e576040516331a9108f60e11b8152600481018390526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610593575f91610527575b50306001600160a01b039091160361051857805f52600560205260405f20600160ff19825416179055805f5260036020528160405f20557f2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb545f80a3005b6335a4e4a560e11b5f5260045ffd5b905060203d60201161058c575b601f8101601f1916820167ffffffffffffffff811183821017610578576020918391604052810103126100ee57516001600160a01b03811681036100ee57836104bb565b634e487b7160e01b5f52604160045260245ffd5b503d610534565b6040513d5f823e3d90fd5b637f184cdb60e11b5f5260045ffd5b346100ee5760803660031901126100ee576105c661065a565b506105cf610670565b5060643567ffffffffffffffff81116100ee57366023820112156100ee57806004013567ffffffffffffffff81116100ee57369101602401116100ee577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361064b57630a85bd0160e11b8152602090f35b63041fb8cb60e31b5f5260045ffd5b600435906001600160a01b03821682036100ee57565b602435906001600160a01b03821682036100ee57565b6001600160a01b03169081156103bf578015610764576040516323b872dd60e01b5f5233600452306024528160445260205f60648180875af160015f5114811615610745575b816040525f6060521561073257825f52600460205260405f209081549280840180941161071e577faf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c74093602093558152a2565b634e487b7160e01b5f52601160045260245ffd5b82635274afe760e01b5f5260045260245ffd5b600181151661075b57833b15153d1516166106cc565b503d5f823e3d90fd5b5050565b5f546001600160a01b031633036102915756fea26469706673582212208d481560aa76d293360090b6d4964b83df3c7cc1923fe964d4b7bc4b2e2011ca64736f6c634300081a0033","sourceMap":"1034:4100:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;:::i;:::-;;;;1619:64;1034:4100;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;1034:4100:12;;;;;;;;;;1738:24:1;1034:4100:12;;;1738:24:1;1034:4100:12;;;;;;;;;1777:43:1;1034:4100:12;1777:43:1;;1034:4100:12;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;1590:22;1034:4100;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;2265:7;1034:4100;-1:-1:-1;;;;;1034:4100:12;2251:10;:21;2247:46;;2303:1;1034:4100;;;2303:1;;:::i;:::-;1034:4100;2247:46;2281:12;;;1034:4100;2281:12;1034:4100;;2281:12;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;1311:13:1;1034:4100:12;735:10:10;-1:-1:-1;;;;;1034:4100:12;;2339:24:1;2335:96;;-1:-1:-1;;;;;;1034:4100:12;;;1311:13:1;1034:4100:12;;;;735:10:10;1034:4100:12;;;;;;;-1:-1:-1;;;;;1034:4100:12;;3052:40:0;;1034:4100:12;3052:40:0;1034:4100:12;2335:96:1;2386:34;;;1034:4100:12;2386:34:1;735:10:10;1034:4100:12;;;;2386:34:1;1034:4100:12;;;;;;-1:-1:-1;;1034:4100:12;;;;;;1544:40;-1:-1:-1;;;;;1034:4100:12;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;2969:28;;;1034:4100;2969:28;1034:4100;;2969:28;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;2483:7:12;1034:4100;;-1:-1:-1;;;;;1034:4100:12;;2479:54;;-1:-1:-1;;;;;1034:4100:12;;2547:22;;2543:48;;-1:-1:-1;;;;;;1034:4100:12;;;2483:7;1034:4100;;;;;;2634:20;;1034:4100;;2634:20;1034:4100;2543:48;2578:13;;;1034:4100;2578:13;1034:4100;;2578:13;2479:54;2513:20;;;1034:4100;2513:20;1034:4100;;2513:20;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;-1:-1:-1;;;;;1034:4100:12;;:::i;:::-;;;;5111:7;1034:4100;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;2265:7;1034:4100;;;;;-1:-1:-1;;;;;1034:4100:12;2251:10;:21;2247:46;;-1:-1:-1;;;;;1034:4100:12;;;;;4158:7;1034:4100;;;;;;;;4154:50;;1034:4100;;-1:-1:-1;;;4218:41:12;;1034:4100;4218:41;;1034:4100;;;;;;;4226:15;-1:-1:-1;;;;;1034:4100:12;4218:41;;;;;;;1034:4100;4218:41;;;1034:4100;-1:-1:-1;4271:4:12;-1:-1:-1;;;;;1034:4100:12;;;4218:58;4214:88;;1034:4100;;;4158:7;1034:4100;;;;;;;;;;;;;;;;;4344:15;1034:4100;;;;;;;4391:30;1034:4100;4391:30;;1034:4100;4214:88;4285:17;;;1034:4100;4285:17;1034:4100;;4285:17;4218:41;;;1034:4100;4218:41;1034:4100;4218:41;;;;1034:4100;;;-1:-1:-1;;1034:4100:12;;;;;;;;;;;;;;;;;;4218:41;;1034:4100;;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;4218:41;;;1034:4100;;;;;;;;;;;;4218:41;;;;;;1034:4100;;;;;;;;;4154:50;4181:23;;;1034:4100;4181:23;1034:4100;;4181:23;1034:4100;;;;;;-1:-1:-1;;1034:4100:12;;;;;;:::i;:::-;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3710:15;-1:-1:-1;;;;;1034:4100:12;3696:10;:29;3692:62;;-1:-1:-1;;;1034:4100:12;;;;;3692:62;3734:20;;;1034:4100;3734:20;1034:4100;;3734:20;1034:4100;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;1034:4100:12;;;;;;:::o;4599:338::-;-1:-1:-1;;;;;1034:4100:12;;4690:19;;4686:45;;4745:11;;4741:24;;11053:1148:8;;11014:28;;;4707:1:12;11053:1148:8;4805:10:12;11053:1148:8;;4825:4:12;11053:1148:8;;;;;;4707:1:12;11053:1148:8;;;;;;1880:4;4707:1:12;11053:1148:8;;;;;;;4599:338:12;11053:1148:8;;;4707:1:12;11053:1148:8;;1837:48;1833:126;;1034:4100:12;4707:1;1034:4100;11053:1148:8;;1034:4100:12;11053:1148:8;4707:1:12;1034:4100;;;;;;;;;;;;;4898:32;1034:4100;11053:1148:8;1034:4100:12;;;;4898:32;4599:338::o;1034:4100::-;;;;4707:1;1034:4100;;11053:1148:8;1034:4100:12;11053:1148:8;4707:1:12;1034:4100;1833:126:8;1908:40;;;;4707:1:12;1908:40:8;11053:1148;1034:4100:12;11053:1148:8;4707:1:12;1908:40:8;11053:1148;1880:4;11053:1148;;;;;;;;;;;;;;;;;;4707:1:12;11053:1148:8;;;;;4741:24:12;4758:7;;:::o;1796:162:0:-;1710:6;1034:4100:12;-1:-1:-1;;;;;1034:4100:12;735:10:10;1855:23:0;1851:101;;1796:162::o","linkReferences":{},"immutableReferences":{"1121":[{"start":697,"length":32},{"start":1155,"length":32},{"start":1550,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"acceptOwnership()","signatureHash4":"0x79ba5097","signatureHash32":"0x79ba5097e5519a381a52113cdcc59540d13f73fd9d26abc0453484a096cc96f2"},{"signature":"factory()","signatureHash4":"0xc45a0155","signatureHash32":"0xc45a01550ceb4bc5c6b2e6f722b5033a03078f9bd6673457375ba94c26ac1cf0"},{"signature":"isLocked(address)","signatureHash4":"0x4a4fbeec","signatureHash32":"0x4a4fbeecd73fa03f3ac781aa98bb4a9c575f180ecd8e77718d48bd03acfef6b0"},{"signature":"lockedPositions(address)","signatureHash4":"0xfa22143d","signatureHash32":"0xfa22143d993c6ad6f61b38974b7f9db2c45068486192977e4dfdebb352aadbea"},{"signature":"lockedTokenSupply(address)","signatureHash4":"0x732e78e4","signatureHash32":"0x732e78e485372c3efb76a43003dc585a6b9fc9dd72982e95fd940236ce3133ce"},{"signature":"lockPosition(address,uint256)","signatureHash4":"0x292d5732","signatureHash32":"0x292d5732bac22fb26986db1f9b8a269415d8df996f5afe290269c5c233fbff82"},{"signature":"lockTokenSupply(address,uint256)","signatureHash4":"0xb8a0d7ab","signatureHash32":"0xb8a0d7abec3cb3941b1f898f79ce2167c3f0943bd5108ddc1d83517c3d72d135"},{"signature":"onERC721Received(address,address,uint256,bytes)","signatureHash4":"0x150b7a02","signatureHash32":"0x150b7a023d4804d13e8c85fb27262cb750cf6ba9f9dd3bb30d90f482ceeb4b1f"},{"signature":"owner()","signatureHash4":"0x8da5cb5b","signatureHash32":"0x8da5cb5b36e7f68c1d2e56001220cdbdd3ba2616072f718acfda4a06441a807d"},{"signature":"pendingOwner()","signatureHash4":"0xe30c3978","signatureHash32":"0xe30c3978ddd82956a01b5cb08d17f1a2d73e636aeefb7b36f896e41d4c2aab90"},{"signature":"positionManager()","signatureHash4":"0x791b98bc","signatureHash32":"0x791b98bc38d035871370995f0afa1d26676383e34628f71308157d4e9c5e95f9"},{"signature":"renounceOwnership()","signatureHash4":"0x715018a6","signatureHash32":"0x715018a616b5f2044428f6fadb7deef4ce9ca76ef60ea57978964ad137bbe7ae"},{"signature":"setFactory(address)","signatureHash4":"0x5bb47808","signatureHash32":"0x5bb478080db4659f0bf53448f830ba5bb3a7143ac6c2cb3ea0e300beb5d46fbf"},{"signature":"transferOwnership(address)","signatureHash4":"0xf2fde38b","signatureHash32":"0xf2fde38b092330466c661fc723d5289b90272a3e580e3187d1d7ef788506c557"}],"event":[{"signature":"FactorySet(address)","signatureHash4":"0x1edf3afd","signatureHash32":"0x1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b1"},{"signature":"OwnershipTransferred(address,address)","signatureHash4":"0x8be0079c","signatureHash32":"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"},{"signature":"OwnershipTransferStarted(address,address)","signatureHash4":"0x38d16b8c","signatureHash32":"0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700"},{"signature":"PositionLocked(address,uint256)","signatureHash4":"0x2cabb2a2","signatureHash32":"0x2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb54"},{"signature":"TokenSupplyLocked(address,uint256)","signatureHash4":"0xaf33c4ab","signatureHash32":"0xaf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c740"}],"error":[{"signature":"AlreadyInitialized()","signatureHash4":"0x0dc149f0","signatureHash32":"0x0dc149f07762891dbcea3fe72770f3d63a1863fc54b2f084e8c59ec476996927"},{"signature":"NotFactory()","signatureHash4":"0x32cc7236","signatureHash32":"0x32cc723614e775fc4a8386492bc9a860c12fe98d5f5f28ec17e265818645b229"},{"signature":"NotPositionManager()","signatureHash4":"0x20fdc658","signatureHash32":"0x20fdc658984fc1865c960399fdc99d034c71c00391e3347558e03d803d4abfd8"},{"signature":"OwnableInvalidOwner(address)","signatureHash4":"0x1e4fbdf7","signatureHash32":"0x1e4fbdf7f3ef8bcaa855599e3abf48b232380f183f08f6f813d9ffa5bd585188"},{"signature":"OwnableUnauthorizedAccount(address)","signatureHash4":"0x118cdaa7","signatureHash32":"0x118cdaa7a341953d1887a2245fd6665d741c67c8c50581daa59e1d03373fa188"},{"signature":"OwnershipCannotBeRenounced()","signatureHash4":"0x2fab92ca","signatureHash32":"0x2fab92ca4da7e80162387e93e02720bc4b98838c093385cac8fecf71a9b7de25"},{"signature":"PositionAlreadyLocked()","signatureHash4":"0xfe3099b6","signatureHash32":"0xfe3099b6228bf2b0aec09cdae2553a0da952c1ce5348f186d757be0c1d441741"},{"signature":"PositionNotHeld()","signatureHash4":"0x6b49c94a","signatureHash32":"0x6b49c94a530e1bf28e24056f5d3721dc966a6d389a642b238e9f0718938c5193"},{"signature":"SafeERC20FailedOperation(address)","signatureHash4":"0x5274afe7","signatureHash32":"0x5274afe73c98b4749fc91ffae6b7b574e7842cb2144a159e9377a5f20b32edf9"},{"signature":"ZeroAddress()","signatureHash4":"0xd92e233d","signatureHash32":"0xd92e233df2717d4a40030e20904abd27b68fcbeede117eaaccbbdac9618c8c73"}]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"match","chainId":"4663","address":"0x267444D099b10fB5Ed7c3Cc7B7c767AdcA574952"}