{"file_path":"src/contracts/ethereum/sfrxUSD/SfrxUSD.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.21;\n\n// ====================================================================\n// |     ______                   _______                             |\n// |    / _____________ __  __   / ____(_____  ____ _____  ________   |\n// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \\/ __ `/ __ \\/ ___/ _ \\  |\n// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |\n// | /_/   /_/   \\__,_/_/|_|  /_/   /_/_/ /_/\\__,_/_/ /_/\\___/\\___/   |\n// |                                                                  |\n// ====================================================================\n// ========================== StakedFrxUSD ============================\n// ====================================================================\n// Frax Finance: https://github.com/FraxFinance\n// Tested for 18-decimal underlying assets only\n\nimport { SfrxUSD3 } from \"src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD3.sol\";\n\ncontract SfrxUSD is SfrxUSD3 {\n    constructor(address _underlying) SfrxUSD3(_underlying) {}\n}\n","deployed_bytecode":"0x608060405234801561000f575f5ffd5b506004361061046f575f3560e01c80637ecebe001161024d578063c6e6f59211610140578063e94a0102116100bf578063f3479dc511610084578063f3479dc514610a3d578063f46eccc414610a46578063f6ccaad414610a68578063fab8693414610a70578063fff6cae914610a83575f5ffd5b8063e94a0102146109de578063ea3418ba14610a22578063ef55bec614610a2a578063ef8b30f714610517578063f0c42cba14610473575f5ffd5b8063d905777e11610105578063d905777e14610606578063dac7c47a1461097b578063dd62ed3e1461098e578063e303dabd146109b8578063e3ee160e146109cb575f5ffd5b8063c6e6f5921461092f578063ce96cb7714610606578063cf09299514610942578063d505accf14610955578063d73ced0414610968575f5ffd5b8063a572711f116101cc578063b460af9411610191578063b460af9414610908578063b7b7289914610916578063ba08765214610908578063bd6f360314610929578063c63d75b614610606575f5ffd5b8063a572711f146108a2578063a80e7547146108bf578063a9059cbb146108e6578063aaf5eb68146108f9578063b3d7f6b914610517575f5ffd5b806395d89b411161021257806395d89b4114610845578063983b2d561461084d578063992a0f891461086057806399530b06146108875780639fd5a6cf1461088f575f5ffd5b80637ecebe00146107b1578063843e3b45146107d057806388b7ab631461082957806390e4595e1461083c57806394bf804d14610738575f5ffd5b8063429b84dc116103655780635ebae566116102e45780636e7e5ac0116102a95780636e7e5ac01461074b57806370a082311461075e57806375e077c31461077d5780637941bc891461078b5780637bf4d9671461079e575f5ffd5b80635ebae566146106d557806361c1c5e9146107145780636917516b1461071c5780636a257ebc146107255780636e553f6514610738575f5ffd5b80634f8b4ae71161032a5780634f8b4ae7146106695780635235387d1461067157806354fd4d501461067a57806356caf6051461069b5780635a049a70146106c2575f5ffd5b8063429b84dc14610627578063446fa44d1461063a57806345014095146106435780634bc66f32146106565780634cdad50614610517575f5ffd5b80631db73bab116103f1578063313ce567116103b6578063313ce5671461059e5780633644e515146105d757806338d52e0f146105df578063402d267d1461060657806342966c6814610614575f5ffd5b80631db73bab1461055357806323b872dd1461055c5780632af98d6d1461056f5780633072cf60146105775780633092afd51461058b575f5ffd5b8063097ce84011610437578063097ce840146105045780630a28a477146105175780630b18d18c1461052a57806316d3bfbb1461053f57806318160ddd1461054a575f5ffd5b806301e1d1141461047357806306fdde031461048e57806307a2d13a146104a3578063090f3f50146104b6578063095ea7b3146104e1575b5f5ffd5b61047b610a8b565b6040519081526020015b60405180910390f35b610496610a9a565b6040516104859190612bcc565b61047b6104b1366004612bde565b610b25565b6011546104c9906001600160a01b031681565b6040516001600160a01b039091168152602001610485565b6104f46104ef366004612c10565b610b51565b6040519015158152602001610485565b600b546104c9906001600160a01b031681565b61047b610525366004612bde565b505f90565b61053d610538366004612c38565b610bbd565b005b61047b6301e1338081565b61047b60025481565b61047b600f5481565b6104f461056a366004612c61565b610c93565b600f5461047b565b6012546104f490600160a01b900460ff1681565b61053d610599366004612c9b565b610d6d565b6105c57f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff9091168152602001610485565b61047b610f17565b6104c97f000000000000000000000000cacd6fd266af91b8aed52accc382b4e165586e2981565b61047b610525366004612c9b565b61053d610622366004612bde565b610f20565b61047b610635366004612bde565b610f62565b61047b60085481565b61053d610651366004612c9b565b610fd1565b6012546104c9906001600160a01b031681565b61053d610fe5565b61047b600c5481565b6040805180820190915260058152640332e302e360dc1b6020820152610496565b61047b7f0000000000000000000000000000000000000000000000000000000000093a8081565b61053d6106d0366004612cc4565b611009565b6106dd61103e565b60408051825164ffffffffff908116825260208085015190911690820152918101516001600160d81b031690820152606001610485565b61047b6110ca565b61047b60105481565b61053d610733366004612c10565b6110d3565b61047b610746366004612d0e565b611151565b61053d610759366004612bde565b61116b565b61047b61076c366004612c9b565b60036020525f908152604090205481565b61047b610746366004612d38565b61053d610799366004612c10565b6111ac565b61053d6107ac366004612bde565b611222565b61047b6107bf366004612c9b565b60056020525f908152604090205481565b6006546007546107fc9164ffffffffff808216926501000000000090920416906001600160d81b031683565b6040805164ffffffffff94851681529390921660208401526001600160d81b031690820152606001610485565b61053d610837366004612e43565b611268565b61047b60095481565b61049661136a565b61053d61085b366004612c9b565b611377565b61047b7f0000000000000000000000000000000000000000001a1601fc4ea7109e00000081565b61047b6114c3565b61053d61089d366004612ec2565b6114cc565b6108aa611595565b60408051928352602083019190915201610485565b61047b7f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b6104f46108f4366004612c10565b6115a8565b61047b670de0b6b3a764000081565b61047b610746366004612f2f565b61053d610924366004612f68565b61160b565b4261047b565b61047b61093d366004612bde565b6116cb565b61053d610950366004612e43565b6116ea565b61053d610963366004612fbb565b611777565b6104c9610976366004612bde565b61178f565b61047b610989366004612bde565b6117b7565b61047b61099c366004613004565b600460209081525f928352604080842090915290825290205481565b61047b6109c6366004612bde565b6117c1565b61053d6109d936600461302c565b6117cb565b6104f46109ec366004612c10565b6001600160a01b03919091165f9081525f5160206133065f395f51905f5260209081526040808320938352929052205460ff1690565b61047b611808565b61053d610a3836600461302c565b611812565b61047b600e5481565b6104f4610a54366004612c9b565b60146020525f908152604090205460ff1681565b61053d611844565b600a546104c9906001600160a01b031681565b61047b611854565b5f610a954261186c565b905090565b5f8054610aa6906130a7565b80601f0160208091040260200160405190810160405280929190818152602001828054610ad2906130a7565b8015610b1d5780601f10610af457610100808354040283529160200191610b1d565b820191905f5260205f20905b815481529060010190602001808311610b0057829003601f168201915b505050505081565b6002545f908015610b4857610b43610b3b610a8b565b849083611896565b610b4a565b825b9392505050565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610bab9086815260200190565b60405180910390a35060015b92915050565b610bc56118b1565b42811115610be6576040516330b7411960e01b815260040160405180910390fd5b600e839055600f82905560108190556040518381527f6f04d943610cd7c69a23bddc3db99c22302184710673a0d770551cd77e7faf819060200160405180910390a16040518281527f5f0d379fa10950c033373bac76c78d7283e5bdf0b72602bb034b7100f8035a239060200160405180910390a16040518181527f560ad0a51ac168674ea5cec12ef8fc50b9cc8be7ff67b0a81dceba82d9c7cba59060200160405180910390a1505050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610cec57610cc883826130f3565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d139084906130f3565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f5160206133265f395f51905f5290610d5a9087815260200190565b60405180910390a3506001949350505050565b610d756118b1565b6001600160a01b038116610dc85760405162461bcd60e51b815260206004820152601560248201527416995c9bc81859191c995cdcc819195d1958dd1959605a1b60448201526064015b60405180910390fd5b6001600160a01b0381165f9081526014602052604090205460ff161515600114610e2a5760405162461bcd60e51b81526020600482015260136024820152721059191c995cdcc81b9bdb995e1a5cdd185b9d606a1b6044820152606401610dbf565b6001600160a01b0381165f908152601460205260408120805460ff191690555b601354811015610ed657816001600160a01b031660138281548110610e7157610e71613106565b5f918252602090912001546001600160a01b031603610ece575f60138281548110610e9e57610e9e613106565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550610ed6565b600101610e4a565b506040516001600160a01b03821681527fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb66692906020015b60405180910390a150565b5f610a956118ba565b610f2a3382611952565b60405181815233907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59060200160405180910390a250565b5f670de0b6b3a7640000821015610f8c57604051631b0848d160e21b815260040160405180910390fd5b5f610f96836119b1565b90507f0000000000000000000000000000000000000000001a1601fc4ea7109e000000610fc9610fc683836119e5565b90565b949350505050565b610fd96118b1565b610fe2816119fc565b50565b610fed6118b1565b610ff5611a4d565b610ffe5f6119fc565b6110075f611a56565b565b61103785858484876040516020016110239392919061311a565b60405160208183030381529060405261160b565b5050505050565b60408051606080820183525f80835260208301819052828401528251908101909252908061108c7f0000000000000000000000000000000000000000000000000000000000093a804261313d565b64ffffffffff9081168252421660208201526040016110ba670de0b6b3a76400006001600160d81b03613164565b6001600160d81b03169052919050565b5f610a95610a8b565b335f9081526014602052604090205460ff16611102576040516338048a8360e01b815260040160405180910390fd5b61110c8282611ab1565b6040518181526001600160a01b0383169033907fe0dcb47e0eb67e20e87f3e34aab31c669ecec7466e8b7fb329d586dadebac6b6906020015b60405180910390a35050565b5f604051634166269960e11b815260040160405180910390fd5b6111736118b1565b42601055600e8190556040518181527f6f04d943610cd7c69a23bddc3db99c22302184710673a0d770551cd77e7faf8190602001610f0c565b335f9081526014602052604090205460ff166111db576040516338048a8360e01b815260040160405180910390fd5b6111e58282611952565b60405181815233906001600160a01b038416907fdc7fd22bc401e7c6b9be2c2736286a2a42ea0c6307bc97ff0fb12bd0abd2c74790602001611145565b61122a6118b1565b611232611854565b50600f8190556040518181527f5f0d379fa10950c033373bac76c78d7283e5bdf0b72602bb034b7100f8035a2390602001610f0c565b6001600160a01b03861633146112a257604051637f54a22160e11b81523360048201526001600160a01b0387166024820152604401610dbf565b8342116112c257604051632ce87eeb60e01b815260040160405180910390fd5b8242106112e25760405163a899ef9360e01b815260040160405180910390fd5b6112ec8783611b00565b61134b877fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de85f1b89898989898960405160200161132f9796959493929190613192565b6040516020818303038152906040528051906020012083611b53565b6113558783611b88565b611360878787611bed565b5050505050505050565b60018054610aa6906130a7565b61137f6118b1565b6001600160a01b0381166113cd5760405162461bcd60e51b815260206004820152601560248201527416995c9bc81859191c995cdcc819195d1958dd1959605a1b6044820152606401610dbf565b6001600160a01b0381165f9081526014602052604090205460ff161561142e5760405162461bcd60e51b81526020600482015260166024820152754164647265737320616c72656164792065786973747360501b6044820152606401610dbf565b6001600160a01b0381165f818152601460209081526040808320805460ff191660019081179091556013805491820181559093527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a09090920180546001600160a01b0319168417905590519182527f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f69101610f0c565b5f610a95611808565b8142111561151c5760405162461bcd60e51b815260206004820152601860248201527f5065726d69743a206578706972656420646561646c696e6500000000000000006044820152606401610dbf565b61158a857f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c987878761154d8b611c6f565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810185905260e00161132f565b611037858585611c9d565b5f5f6115a042611cfd565b915091509091565b335f908152600360205260408120805483919083906115c89084906130f3565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f5160206133265f395f51905f5290610bab9086815260200190565b6116158383611b00565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b038516918101919091526060810183905261166590849060800161132f565b6001600160a01b0383165f8181525f5160206133065f395f51905f5260209081526040808320868452909152808220805460ff19166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b6002545f908015610b4857610b43816116e2610a8b565b859190611896565b83421161170a57604051632ce87eeb60e01b815260040160405180910390fd5b82421061172a5760405163a899ef9360e01b815260040160405180910390fd5b6117348783611b00565b61134b877f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22675f1b89898989898960405160200161132f9796959493929190613192565b61178687878787878787611d1a565b50505050505050565b6013818154811061179e575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f610bb78261186c565b5f610bb782611d4a565b6117fd89898989898988888b6040516020016117e99392919061311a565b6040516020818303038152906040526116ea565b505050505050505050565b5f610a9542611d4a565b6117fd89898989898988888b6040516020016118309392919061311a565b604051602081830303815290604052611268565b61184c611a4d565b611007611d9a565b5f61185e42611d4a565b600e81905542601055919050565b5f670de0b6b3a764000060025461188284611d4a565b61188c91906131ce565b610bb791906131e5565b5f825f1904841183021582026118aa575f5ffd5b5091020490565b61100733611db3565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f6040516118ea91906131f8565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0382165f90815260036020526040812080548392906119799084906130f3565b90915550506002805482900390556040518181525f906001600160a01b038416905f5160206133265f395f51905f5290602001611145565b5f610bb76714057b7ef767814f670de0b6b3a76400006119d3610fc686611df8565b02816119e1576119e1613150565b0490565b5f610b4a610fc684670de0b6b3a764000085611f2c565b601180546001600160a01b0319166001600160a01b03838116918217909255601254604051919216907f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a905f90a350565b61100733611ffb565b6012546040516001600160a01b038084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3601280546001600160a01b0319166001600160a01b0392909216919091179055565b8060025f828254611ac2919061313d565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f5160206133265f395f51905f529101611145565b5f5160206133065f395f51905f526001600160a01b0383165f90815260209182526040808220848352909252205460ff1615611b4f5760405163076f007560e21b815260040160405180910390fd5b5050565b611b6683611b6084612040565b83612086565b611b8357604051638baa579f60e01b815260040160405180910390fd5b505050565b6001600160a01b0382165f8181525f5160206133065f395f51905f5260209081526040808320858452909152808220805460ff19166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6001600160a01b0383165f90815260036020526040812080548391908390611c169084906130f3565b90915550506001600160a01b038084165f81815260036020526040908190208054860190555190918616905f5160206133265f395f51905f5290611c5d9086815260200190565b60405180910390a35060019392505050565b6001600160a01b0381165f90815260056020526040812080549082611c9383613294565b9091555092915050565b6001600160a01b038381165f8181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f5f611d0883611d4a565b9150611d138361186c565b9050915091565b61178687878787868689604051602001611d369392919061311a565b6040516020818303038152906040526114cc565b5f5f60105483611d5a91906130f3565b90505f611d6e82600f54610fc691906131ce565b90505f611d7a826120f6565b9050611d91610fc6611d8b600e5490565b83612143565b95945050505050565b601180546001600160a01b031916905561100733611a56565b6012546001600160a01b03828116911614610fe25760125460405163110f70ad60e21b81526001600160a01b0391821660048201529082166024820152604401610dbf565b5f81670de0b6b3a7640000811015611e265760405163036d32ef60e41b815260048101849052602401610dbf565b5f611eb1670de0b6b3a7640000830460016fffffffffffffffffffffffffffffffff821160071b91821c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211871b91821c969096119490961792909217171791909117919091171790565b9050670de0b6b3a7640000810282821c670de0b6b3a763ffff198101611edd57815b9695505050505050565b671bc16d674ec800006706f05b59d3b200005b8015611f2057670de0b6b3a7640000838002049250818310611f18579283019260019290921c915b60011c611ef0565b50919695505050505050565b5f80805f19858709858702925082811083820303915050805f03611f6357838281611f5957611f59613150565b0492505050610b4a565b838110611f9457604051630c740aef60e31b8152600481018790526024810186905260448101859052606401610dbf565b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b6011546001600160a01b03828116911614610fe25760115460405163be5a953760e01b81526001600160a01b0391821660048201529082166024820152604401610dbf565b5f612049610f17565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050919050565b5f836001600160a01b03163b5f036120e4575f5f6120a48585612151565b5090925090505f8160038111156120bd576120bd6132ac565b1480156120db5750856001600160a01b0316826001600160a01b0316145b92505050610b4a565b6120ef84848461219a565b9050610b4a565b5f81680736ea4425c11ac63081111561212557604051630d7b1d6560e11b815260048101849052602401610dbf565b6714057b7ef767814f8102610fc9670de0b6b3a76400008204612270565b5f610b4a610fc684846122c4565b5f5f5f8351604103612188576020840151604085015160608601515f1a61217a88828585612376565b955095509550505050612193565b505081515f91506002905b9250925092565b5f5f5f856001600160a01b031685856040516024016121ba9291906132c0565b60408051601f198184030181529181526020820180516001600160e01b0316630b135d3f60e11b179052516121ef91906132d8565b5f60405180830381855afa9150503d805f8114612227576040519150601f19603f3d011682016040523d82523d5f602084013e61222c565b606091505b509150915081801561224057506020815110155b8015611ed357508051630b135d3f60e11b9061226590830160209081019084016132ee565b149695505050505050565b5f81680a688906bd8affffff81111561229f5760405163b3b6ba1f60e01b815260048101849052602401610dbf565b5f6122b6670de0b6b3a7640000604084901b6131e5565b9050610fc9610fc68261243e565b5f80805f19848609848602925082811083820303915050805f036122f55750670de0b6b3a764000090049050610bb7565b670de0b6b3a7640000811061232757604051635173648d60e01b81526004810186905260248101859052604401610dbf565b5f670de0b6b3a764000085870962040000818503049310909103600160ee1b02919091177faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106690291505092915050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156123af57505f91506003905082612434565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015612400573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661242b57505f925060019150829050612434565b92505f91508190505b9450945094915050565b600160bf1b67ff0000000000000082161561254b576780000000000000008216156124725768016a09e667f3bcc9090260401c5b674000000000000000821615612491576801306fe0a31b7152df0260401c5b6720000000000000008216156124b0576801172b83c7d517adce0260401c5b6710000000000000008216156124cf5768010b5586cf9890f62a0260401c5b6708000000000000008216156124ee576801059b0d31585743ae0260401c5b67040000000000000082161561250d57680102c9a3e778060ee70260401c5b67020000000000000082161561252c5768010163da9fb33356d80260401c5b67010000000000000082161561254b57680100b1afa5abcbed610260401c5b66ff00000000000082161561264a5766800000000000008216156125785768010058c86da1c09ea20260401c5b6640000000000000821615612596576801002c605e2e8cec500260401c5b66200000000000008216156125b457680100162f3904051fa10260401c5b66100000000000008216156125d2576801000b175effdc76ba0260401c5b66080000000000008216156125f057680100058ba01fb9f96d0260401c5b660400000000000082161561260e5768010002c5cc37da94920260401c5b660200000000000082161561262c576801000162e525ee05470260401c5b660100000000000082161561264a5768010000b17255775c040260401c5b65ff00000000008216156127405765800000000000821615612675576801000058b91b5bc9ae0260401c5b6540000000000082161561269257680100002c5c89d5ec6d0260401c5b652000000000008216156126af5768010000162e43f4f8310260401c5b651000000000008216156126cc57680100000b1721bcfc9a0260401c5b650800000000008216156126e95768010000058b90cf1e6e0260401c5b65040000000000821615612706576801000002c5c863b73f0260401c5b6502000000000082161561272357680100000162e430e5a20260401c5b65010000000000821615612740576801000000b1721835510260401c5b64ff0000000082161561282d5764800000000082161561276957680100000058b90c0b490260401c5b6440000000008216156127855768010000002c5c8601cc0260401c5b6420000000008216156127a1576801000000162e42fff00260401c5b6410000000008216156127bd5768010000000b17217fbb0260401c5b6408000000008216156127d9576801000000058b90bfce0260401c5b6404000000008216156127f557680100000002c5c85fe30260401c5b6402000000008216156128115768010000000162e42ff10260401c5b64010000000082161561282d57680100000000b17217f80260401c5b63ff0000008216156129115763800000008216156128545768010000000058b90bfc0260401c5b634000000082161561286f576801000000002c5c85fe0260401c5b632000000082161561288a57680100000000162e42ff0260401c5b63100000008216156128a5576801000000000b17217f0260401c5b63080000008216156128c057680100000000058b90c00260401c5b63040000008216156128db5768010000000002c5c8600260401c5b63020000008216156128f6576801000000000162e4300260401c5b63010000008216156129115768010000000000b172180260401c5b62ff00008216156129ec5762800000821615612936576801000000000058b90c0260401c5b6240000082161561295057680100000000002c5c860260401c5b6220000082161561296a5768010000000000162e430260401c5b6210000082161561298457680100000000000b17210260401c5b6208000082161561299e5768010000000000058b910260401c5b620400008216156129b8576801000000000002c5c80260401c5b620200008216156129d257680100000000000162e40260401c5b620100008216156129ec576801000000000000b1720260401c5b61ff00821615612abe57618000821615612a0f57680100000000000058b90260401c5b614000821615612a285768010000000000002c5d0260401c5b612000821615612a41576801000000000000162e0260401c5b611000821615612a5a5768010000000000000b170260401c5b610800821615612a73576801000000000000058c0260401c5b610400821615612a8c57680100000000000002c60260401c5b610200821615612aa557680100000000000001630260401c5b610100821615612abe57680100000000000000b10260401c5b60ff821615612b87576080821615612adf57680100000000000000590260401c5b6040821615612af7576801000000000000002c0260401c5b6020821615612b0f57680100000000000000160260401c5b6010821615612b27576801000000000000000b0260401c5b6008821615612b3f57680100000000000000060260401c5b6004821615612b5757680100000000000000030260401c5b6002821615612b6f57680100000000000000010260401c5b6001821615612b8757680100000000000000010260401c5b670de0b6b3a76400000260409190911c60bf031c90565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610b4a6020830184612b9e565b5f60208284031215612bee575f5ffd5b5035919050565b80356001600160a01b0381168114612c0b575f5ffd5b919050565b5f5f60408385031215612c21575f5ffd5b612c2a83612bf5565b946020939093013593505050565b5f5f5f60608486031215612c4a575f5ffd5b505081359360208301359350604090920135919050565b5f5f5f60608486031215612c73575f5ffd5b612c7c84612bf5565b9250612c8a60208501612bf5565b929592945050506040919091013590565b5f60208284031215612cab575f5ffd5b610b4a82612bf5565b803560ff81168114612c0b575f5ffd5b5f5f5f5f5f60a08688031215612cd8575f5ffd5b612ce186612bf5565b945060208601359350612cf660408701612cb4565b94979396509394606081013594506080013592915050565b5f5f60408385031215612d1f575f5ffd5b82359150612d2f60208401612bf5565b90509250929050565b5f5f5f5f5f5f5f60e0888a031215612d4e575f5ffd5b87359650612d5e60208901612bf5565b95506040880135945060608801358015158114612d79575f5ffd5b9350612d8760808901612cb4565b9699959850939692959460a0840135945060c09093013592915050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112612dc7575f5ffd5b813567ffffffffffffffff811115612de157612de1612da4565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715612e1057612e10612da4565b604052818152838201602001851015612e27575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f5f5f60e0888a031215612e59575f5ffd5b612e6288612bf5565b9650612e7060208901612bf5565b955060408801359450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff811115612ea7575f5ffd5b612eb38a828b01612db8565b91505092959891949750929550565b5f5f5f5f5f60a08688031215612ed6575f5ffd5b612edf86612bf5565b9450612eed60208701612bf5565b93506040860135925060608601359150608086013567ffffffffffffffff811115612f16575f5ffd5b612f2288828901612db8565b9150509295509295909350565b5f5f5f60608486031215612f41575f5ffd5b83359250612f5160208501612bf5565b9150612f5f60408501612bf5565b90509250925092565b5f5f5f60608486031215612f7a575f5ffd5b612f8384612bf5565b925060208401359150604084013567ffffffffffffffff811115612fa5575f5ffd5b612fb186828701612db8565b9150509250925092565b5f5f5f5f5f5f5f60e0888a031215612fd1575f5ffd5b612fda88612bf5565b9650612fe860208901612bf5565b95506040880135945060608801359350612d8760808901612cb4565b5f5f60408385031215613015575f5ffd5b61301e83612bf5565b9150612d2f60208401612bf5565b5f5f5f5f5f5f5f5f5f6101208a8c031215613045575f5ffd5b61304e8a612bf5565b985061305c60208b01612bf5565b975060408a0135965060608a0135955060808a0135945060a08a0135935061308660c08b01612cb4565b989b979a50959894979396929550929360e081013593506101000135919050565b600181811c908216806130bb57607f821691505b6020821081036130d957634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610bb757610bb76130df565b634e487b7160e01b5f52603260045260245ffd5b928352602083019190915260f81b6001600160f81b031916604082015260410190565b80820180821115610bb757610bb76130df565b634e487b7160e01b5f52601260045260245ffd5b5f6001600160d81b0383168061317c5761317c613150565b6001600160d81b03929092169190910492915050565b9687526001600160a01b0395861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b8082028115828204841417610bb757610bb76130df565b5f826131f3576131f3613150565b500490565b5f5f83545f8160011c9050600182168061321357607f821691505b60208210810361323157634e487b7160e01b5f52602260045260245ffd5b808015613245576001811461325a57613288565b60ff1984168752821515830287019450613288565b5f888152602090205f5b8481101561328057815489820152600190910190602001613264565b505082870194505b50929695505050505050565b5f600182016132a5576132a56130df565b5060010190565b634e487b7160e01b5f52602160045260245ffd5b828152604060208201525f610fc96040830184612b9e565b5f82518060208501845e5f920191825250919050565b5f602082840312156132fe575f5ffd5b505191905056fe6607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"prague","libraries":{},"metadata":{"appendCBOR":false,"bytecodeHash":"none","useLiteralContent":false},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["frax-std/=node_modules/frax-standard-solidity/src/","@prb/math/=node_modules/@prb/math/","forge-std/=node_modules/forge-std/src/","ds-test/=node_modules/ds-test/src/","@openzeppelin/=node_modules/@openzeppelin/","solmate/=node_modules/solmate/src/","@fraxfinance/=node_modules/@fraxfinance/","@layerzerolabs/=node_modules/@layerzerolabs/","frax-standard-solidity/=node_modules/frax-standard-solidity/","hardhat-deploy/=node_modules/hardhat-deploy/","solidity-bytes-utils/=node_modules/solidity-bytes-utils/"],"viaIR":false},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":[["0xCAcd6fd266aF91b8AeD52aCCc382b4e165586E29",{"internalType":"address","name":"_underlying","type":"address"}]],"compiler_version":"v0.8.30+commit.73712a01","is_verified_via_verifier_alliance":false,"verified_at":"2026-01-27T06:03:51.591413Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x61016060405262093a8061010052348015610018575f5ffd5b50604051613a1c380380613a1c83398101604081905261003791610347565b80806040518060400160405280600f81526020016e14dd185ad95908119c985e081554d1608a1b815250604051806040016040528060078152602001661cd99c9e1554d160ca1b8152505f808484848282828181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100eb9190610374565b5f6100f6848261042c565b506001610103838261042c565b5060ff81166080524660a052610117610266565b60c0525050506001600160a01b0392831660e05250506040805163313ce56760e01b815290519185169163313ce567916004808201926020929091908290030181865afa15801561016a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018e9190610374565b60ff166012146101b157604051637255a60160e01b815260040160405180910390fd5b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101ed573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102119190610374565b61021c90600a6105df565b6101405261022d6301e133806102fe565b610120525050601280546001600160a81b0319166001600160a01b0390931692909217600160a01b179091555061067d95505050505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f60405161029691906105ed565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f610312670de0b6b3a76400005f1961065e565b82111561033957604051631cd951a760e01b81526004810183905260240160405180910390fd5b50670de0b6b3a76400000290565b5f60208284031215610357575f5ffd5b81516001600160a01b038116811461036d575f5ffd5b9392505050565b5f60208284031215610384575f5ffd5b815160ff8116811461036d575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806103bc57607f821691505b6020821081036103da57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561042757805f5260205f20601f840160051c810160208510156104055750805b601f840160051c820191505b81811015610424575f8155600101610411565b50505b505050565b81516001600160401b0381111561044557610445610394565b6104598161045384546103a8565b846103e0565b6020601f82116001811461048b575f83156104745750848201515b5f19600385901b1c1916600184901b178455610424565b5f84815260208120601f198516915b828110156104ba578785015182556020948501946001909201910161049a565b50848210156104d757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b6001815b600184111561053557808504811115610519576105196104e6565b600184161561052757908102905b60019390931c9280026104fe565b935093915050565b5f8261054b575060016105d9565b8161055757505f6105d9565b816001811461056d576002811461057757610593565b60019150506105d9565b60ff841115610588576105886104e6565b50506001821b6105d9565b5060208310610133831016604e8410600b84101617156105b6575081810a6105d9565b6105c25f1984846104fa565b805f19048211156105d5576105d56104e6565b0290505b92915050565b5f61036d60ff84168361053d565b5f5f83546105fa816103a8565b600182168015610611576001811461062657610653565b60ff1983168652811515820286019350610653565b865f5260205f205f5b8381101561064b5781548882015260019091019060200161062f565b505081860193505b509195945050505050565b5f8261067857634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e0516101005161012051610140516133466106d65f395f6108c401525f81816108650152610f9a01525f81816106a0015261106701525f6105e401525f50505f50505f6105a301526133465ff3fe608060405234801561000f575f5ffd5b506004361061046f575f3560e01c80637ecebe001161024d578063c6e6f59211610140578063e94a0102116100bf578063f3479dc511610084578063f3479dc514610a3d578063f46eccc414610a46578063f6ccaad414610a68578063fab8693414610a70578063fff6cae914610a83575f5ffd5b8063e94a0102146109de578063ea3418ba14610a22578063ef55bec614610a2a578063ef8b30f714610517578063f0c42cba14610473575f5ffd5b8063d905777e11610105578063d905777e14610606578063dac7c47a1461097b578063dd62ed3e1461098e578063e303dabd146109b8578063e3ee160e146109cb575f5ffd5b8063c6e6f5921461092f578063ce96cb7714610606578063cf09299514610942578063d505accf14610955578063d73ced0414610968575f5ffd5b8063a572711f116101cc578063b460af9411610191578063b460af9414610908578063b7b7289914610916578063ba08765214610908578063bd6f360314610929578063c63d75b614610606575f5ffd5b8063a572711f146108a2578063a80e7547146108bf578063a9059cbb146108e6578063aaf5eb68146108f9578063b3d7f6b914610517575f5ffd5b806395d89b411161021257806395d89b4114610845578063983b2d561461084d578063992a0f891461086057806399530b06146108875780639fd5a6cf1461088f575f5ffd5b80637ecebe00146107b1578063843e3b45146107d057806388b7ab631461082957806390e4595e1461083c57806394bf804d14610738575f5ffd5b8063429b84dc116103655780635ebae566116102e45780636e7e5ac0116102a95780636e7e5ac01461074b57806370a082311461075e57806375e077c31461077d5780637941bc891461078b5780637bf4d9671461079e575f5ffd5b80635ebae566146106d557806361c1c5e9146107145780636917516b1461071c5780636a257ebc146107255780636e553f6514610738575f5ffd5b80634f8b4ae71161032a5780634f8b4ae7146106695780635235387d1461067157806354fd4d501461067a57806356caf6051461069b5780635a049a70146106c2575f5ffd5b8063429b84dc14610627578063446fa44d1461063a57806345014095146106435780634bc66f32146106565780634cdad50614610517575f5ffd5b80631db73bab116103f1578063313ce567116103b6578063313ce5671461059e5780633644e515146105d757806338d52e0f146105df578063402d267d1461060657806342966c6814610614575f5ffd5b80631db73bab1461055357806323b872dd1461055c5780632af98d6d1461056f5780633072cf60146105775780633092afd51461058b575f5ffd5b8063097ce84011610437578063097ce840146105045780630a28a477146105175780630b18d18c1461052a57806316d3bfbb1461053f57806318160ddd1461054a575f5ffd5b806301e1d1141461047357806306fdde031461048e57806307a2d13a146104a3578063090f3f50146104b6578063095ea7b3146104e1575b5f5ffd5b61047b610a8b565b6040519081526020015b60405180910390f35b610496610a9a565b6040516104859190612bcc565b61047b6104b1366004612bde565b610b25565b6011546104c9906001600160a01b031681565b6040516001600160a01b039091168152602001610485565b6104f46104ef366004612c10565b610b51565b6040519015158152602001610485565b600b546104c9906001600160a01b031681565b61047b610525366004612bde565b505f90565b61053d610538366004612c38565b610bbd565b005b61047b6301e1338081565b61047b60025481565b61047b600f5481565b6104f461056a366004612c61565b610c93565b600f5461047b565b6012546104f490600160a01b900460ff1681565b61053d610599366004612c9b565b610d6d565b6105c57f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610485565b61047b610f17565b6104c97f000000000000000000000000000000000000000000000000000000000000000081565b61047b610525366004612c9b565b61053d610622366004612bde565b610f20565b61047b610635366004612bde565b610f62565b61047b60085481565b61053d610651366004612c9b565b610fd1565b6012546104c9906001600160a01b031681565b61053d610fe5565b61047b600c5481565b6040805180820190915260058152640332e302e360dc1b6020820152610496565b61047b7f000000000000000000000000000000000000000000000000000000000000000081565b61053d6106d0366004612cc4565b611009565b6106dd61103e565b60408051825164ffffffffff908116825260208085015190911690820152918101516001600160d81b031690820152606001610485565b61047b6110ca565b61047b60105481565b61053d610733366004612c10565b6110d3565b61047b610746366004612d0e565b611151565b61053d610759366004612bde565b61116b565b61047b61076c366004612c9b565b60036020525f908152604090205481565b61047b610746366004612d38565b61053d610799366004612c10565b6111ac565b61053d6107ac366004612bde565b611222565b61047b6107bf366004612c9b565b60056020525f908152604090205481565b6006546007546107fc9164ffffffffff808216926501000000000090920416906001600160d81b031683565b6040805164ffffffffff94851681529390921660208401526001600160d81b031690820152606001610485565b61053d610837366004612e43565b611268565b61047b60095481565b61049661136a565b61053d61085b366004612c9b565b611377565b61047b7f000000000000000000000000000000000000000000000000000000000000000081565b61047b6114c3565b61053d61089d366004612ec2565b6114cc565b6108aa611595565b60408051928352602083019190915201610485565b61047b7f000000000000000000000000000000000000000000000000000000000000000081565b6104f46108f4366004612c10565b6115a8565b61047b670de0b6b3a764000081565b61047b610746366004612f2f565b61053d610924366004612f68565b61160b565b4261047b565b61047b61093d366004612bde565b6116cb565b61053d610950366004612e43565b6116ea565b61053d610963366004612fbb565b611777565b6104c9610976366004612bde565b61178f565b61047b610989366004612bde565b6117b7565b61047b61099c366004613004565b600460209081525f928352604080842090915290825290205481565b61047b6109c6366004612bde565b6117c1565b61053d6109d936600461302c565b6117cb565b6104f46109ec366004612c10565b6001600160a01b03919091165f9081525f5160206133065f395f51905f5260209081526040808320938352929052205460ff1690565b61047b611808565b61053d610a3836600461302c565b611812565b61047b600e5481565b6104f4610a54366004612c9b565b60146020525f908152604090205460ff1681565b61053d611844565b600a546104c9906001600160a01b031681565b61047b611854565b5f610a954261186c565b905090565b5f8054610aa6906130a7565b80601f0160208091040260200160405190810160405280929190818152602001828054610ad2906130a7565b8015610b1d5780601f10610af457610100808354040283529160200191610b1d565b820191905f5260205f20905b815481529060010190602001808311610b0057829003601f168201915b505050505081565b6002545f908015610b4857610b43610b3b610a8b565b849083611896565b610b4a565b825b9392505050565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610bab9086815260200190565b60405180910390a35060015b92915050565b610bc56118b1565b42811115610be6576040516330b7411960e01b815260040160405180910390fd5b600e839055600f82905560108190556040518381527f6f04d943610cd7c69a23bddc3db99c22302184710673a0d770551cd77e7faf819060200160405180910390a16040518281527f5f0d379fa10950c033373bac76c78d7283e5bdf0b72602bb034b7100f8035a239060200160405180910390a16040518181527f560ad0a51ac168674ea5cec12ef8fc50b9cc8be7ff67b0a81dceba82d9c7cba59060200160405180910390a1505050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610cec57610cc883826130f3565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d139084906130f3565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f5160206133265f395f51905f5290610d5a9087815260200190565b60405180910390a3506001949350505050565b610d756118b1565b6001600160a01b038116610dc85760405162461bcd60e51b815260206004820152601560248201527416995c9bc81859191c995cdcc819195d1958dd1959605a1b60448201526064015b60405180910390fd5b6001600160a01b0381165f9081526014602052604090205460ff161515600114610e2a5760405162461bcd60e51b81526020600482015260136024820152721059191c995cdcc81b9bdb995e1a5cdd185b9d606a1b6044820152606401610dbf565b6001600160a01b0381165f908152601460205260408120805460ff191690555b601354811015610ed657816001600160a01b031660138281548110610e7157610e71613106565b5f918252602090912001546001600160a01b031603610ece575f60138281548110610e9e57610e9e613106565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550610ed6565b600101610e4a565b506040516001600160a01b03821681527fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb66692906020015b60405180910390a150565b5f610a956118ba565b610f2a3382611952565b60405181815233907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59060200160405180910390a250565b5f670de0b6b3a7640000821015610f8c57604051631b0848d160e21b815260040160405180910390fd5b5f610f96836119b1565b90507f0000000000000000000000000000000000000000000000000000000000000000610fc9610fc683836119e5565b90565b949350505050565b610fd96118b1565b610fe2816119fc565b50565b610fed6118b1565b610ff5611a4d565b610ffe5f6119fc565b6110075f611a56565b565b61103785858484876040516020016110239392919061311a565b60405160208183030381529060405261160b565b5050505050565b60408051606080820183525f80835260208301819052828401528251908101909252908061108c7f00000000000000000000000000000000000000000000000000000000000000004261313d565b64ffffffffff9081168252421660208201526040016110ba670de0b6b3a76400006001600160d81b03613164565b6001600160d81b03169052919050565b5f610a95610a8b565b335f9081526014602052604090205460ff16611102576040516338048a8360e01b815260040160405180910390fd5b61110c8282611ab1565b6040518181526001600160a01b0383169033907fe0dcb47e0eb67e20e87f3e34aab31c669ecec7466e8b7fb329d586dadebac6b6906020015b60405180910390a35050565b5f604051634166269960e11b815260040160405180910390fd5b6111736118b1565b42601055600e8190556040518181527f6f04d943610cd7c69a23bddc3db99c22302184710673a0d770551cd77e7faf8190602001610f0c565b335f9081526014602052604090205460ff166111db576040516338048a8360e01b815260040160405180910390fd5b6111e58282611952565b60405181815233906001600160a01b038416907fdc7fd22bc401e7c6b9be2c2736286a2a42ea0c6307bc97ff0fb12bd0abd2c74790602001611145565b61122a6118b1565b611232611854565b50600f8190556040518181527f5f0d379fa10950c033373bac76c78d7283e5bdf0b72602bb034b7100f8035a2390602001610f0c565b6001600160a01b03861633146112a257604051637f54a22160e11b81523360048201526001600160a01b0387166024820152604401610dbf565b8342116112c257604051632ce87eeb60e01b815260040160405180910390fd5b8242106112e25760405163a899ef9360e01b815260040160405180910390fd5b6112ec8783611b00565b61134b877fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de85f1b89898989898960405160200161132f9796959493929190613192565b6040516020818303038152906040528051906020012083611b53565b6113558783611b88565b611360878787611bed565b5050505050505050565b60018054610aa6906130a7565b61137f6118b1565b6001600160a01b0381166113cd5760405162461bcd60e51b815260206004820152601560248201527416995c9bc81859191c995cdcc819195d1958dd1959605a1b6044820152606401610dbf565b6001600160a01b0381165f9081526014602052604090205460ff161561142e5760405162461bcd60e51b81526020600482015260166024820152754164647265737320616c72656164792065786973747360501b6044820152606401610dbf565b6001600160a01b0381165f818152601460209081526040808320805460ff191660019081179091556013805491820181559093527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a09090920180546001600160a01b0319168417905590519182527f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f69101610f0c565b5f610a95611808565b8142111561151c5760405162461bcd60e51b815260206004820152601860248201527f5065726d69743a206578706972656420646561646c696e6500000000000000006044820152606401610dbf565b61158a857f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c987878761154d8b611c6f565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810185905260e00161132f565b611037858585611c9d565b5f5f6115a042611cfd565b915091509091565b335f908152600360205260408120805483919083906115c89084906130f3565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f5160206133265f395f51905f5290610bab9086815260200190565b6116158383611b00565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b038516918101919091526060810183905261166590849060800161132f565b6001600160a01b0383165f8181525f5160206133065f395f51905f5260209081526040808320868452909152808220805460ff19166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b6002545f908015610b4857610b43816116e2610a8b565b859190611896565b83421161170a57604051632ce87eeb60e01b815260040160405180910390fd5b82421061172a5760405163a899ef9360e01b815260040160405180910390fd5b6117348783611b00565b61134b877f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22675f1b89898989898960405160200161132f9796959493929190613192565b61178687878787878787611d1a565b50505050505050565b6013818154811061179e575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f610bb78261186c565b5f610bb782611d4a565b6117fd89898989898988888b6040516020016117e99392919061311a565b6040516020818303038152906040526116ea565b505050505050505050565b5f610a9542611d4a565b6117fd89898989898988888b6040516020016118309392919061311a565b604051602081830303815290604052611268565b61184c611a4d565b611007611d9a565b5f61185e42611d4a565b600e81905542601055919050565b5f670de0b6b3a764000060025461188284611d4a565b61188c91906131ce565b610bb791906131e5565b5f825f1904841183021582026118aa575f5ffd5b5091020490565b61100733611db3565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f6040516118ea91906131f8565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0382165f90815260036020526040812080548392906119799084906130f3565b90915550506002805482900390556040518181525f906001600160a01b038416905f5160206133265f395f51905f5290602001611145565b5f610bb76714057b7ef767814f670de0b6b3a76400006119d3610fc686611df8565b02816119e1576119e1613150565b0490565b5f610b4a610fc684670de0b6b3a764000085611f2c565b601180546001600160a01b0319166001600160a01b03838116918217909255601254604051919216907f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a905f90a350565b61100733611ffb565b6012546040516001600160a01b038084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3601280546001600160a01b0319166001600160a01b0392909216919091179055565b8060025f828254611ac2919061313d565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f5160206133265f395f51905f529101611145565b5f5160206133065f395f51905f526001600160a01b0383165f90815260209182526040808220848352909252205460ff1615611b4f5760405163076f007560e21b815260040160405180910390fd5b5050565b611b6683611b6084612040565b83612086565b611b8357604051638baa579f60e01b815260040160405180910390fd5b505050565b6001600160a01b0382165f8181525f5160206133065f395f51905f5260209081526040808320858452909152808220805460ff19166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6001600160a01b0383165f90815260036020526040812080548391908390611c169084906130f3565b90915550506001600160a01b038084165f81815260036020526040908190208054860190555190918616905f5160206133265f395f51905f5290611c5d9086815260200190565b60405180910390a35060019392505050565b6001600160a01b0381165f90815260056020526040812080549082611c9383613294565b9091555092915050565b6001600160a01b038381165f8181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f5f611d0883611d4a565b9150611d138361186c565b9050915091565b61178687878787868689604051602001611d369392919061311a565b6040516020818303038152906040526114cc565b5f5f60105483611d5a91906130f3565b90505f611d6e82600f54610fc691906131ce565b90505f611d7a826120f6565b9050611d91610fc6611d8b600e5490565b83612143565b95945050505050565b601180546001600160a01b031916905561100733611a56565b6012546001600160a01b03828116911614610fe25760125460405163110f70ad60e21b81526001600160a01b0391821660048201529082166024820152604401610dbf565b5f81670de0b6b3a7640000811015611e265760405163036d32ef60e41b815260048101849052602401610dbf565b5f611eb1670de0b6b3a7640000830460016fffffffffffffffffffffffffffffffff821160071b91821c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211871b91821c969096119490961792909217171791909117919091171790565b9050670de0b6b3a7640000810282821c670de0b6b3a763ffff198101611edd57815b9695505050505050565b671bc16d674ec800006706f05b59d3b200005b8015611f2057670de0b6b3a7640000838002049250818310611f18579283019260019290921c915b60011c611ef0565b50919695505050505050565b5f80805f19858709858702925082811083820303915050805f03611f6357838281611f5957611f59613150565b0492505050610b4a565b838110611f9457604051630c740aef60e31b8152600481018790526024810186905260448101859052606401610dbf565b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b6011546001600160a01b03828116911614610fe25760115460405163be5a953760e01b81526001600160a01b0391821660048201529082166024820152604401610dbf565b5f612049610f17565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050919050565b5f836001600160a01b03163b5f036120e4575f5f6120a48585612151565b5090925090505f8160038111156120bd576120bd6132ac565b1480156120db5750856001600160a01b0316826001600160a01b0316145b92505050610b4a565b6120ef84848461219a565b9050610b4a565b5f81680736ea4425c11ac63081111561212557604051630d7b1d6560e11b815260048101849052602401610dbf565b6714057b7ef767814f8102610fc9670de0b6b3a76400008204612270565b5f610b4a610fc684846122c4565b5f5f5f8351604103612188576020840151604085015160608601515f1a61217a88828585612376565b955095509550505050612193565b505081515f91506002905b9250925092565b5f5f5f856001600160a01b031685856040516024016121ba9291906132c0565b60408051601f198184030181529181526020820180516001600160e01b0316630b135d3f60e11b179052516121ef91906132d8565b5f60405180830381855afa9150503d805f8114612227576040519150601f19603f3d011682016040523d82523d5f602084013e61222c565b606091505b509150915081801561224057506020815110155b8015611ed357508051630b135d3f60e11b9061226590830160209081019084016132ee565b149695505050505050565b5f81680a688906bd8affffff81111561229f5760405163b3b6ba1f60e01b815260048101849052602401610dbf565b5f6122b6670de0b6b3a7640000604084901b6131e5565b9050610fc9610fc68261243e565b5f80805f19848609848602925082811083820303915050805f036122f55750670de0b6b3a764000090049050610bb7565b670de0b6b3a7640000811061232757604051635173648d60e01b81526004810186905260248101859052604401610dbf565b5f670de0b6b3a764000085870962040000818503049310909103600160ee1b02919091177faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106690291505092915050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156123af57505f91506003905082612434565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015612400573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661242b57505f925060019150829050612434565b92505f91508190505b9450945094915050565b600160bf1b67ff0000000000000082161561254b576780000000000000008216156124725768016a09e667f3bcc9090260401c5b674000000000000000821615612491576801306fe0a31b7152df0260401c5b6720000000000000008216156124b0576801172b83c7d517adce0260401c5b6710000000000000008216156124cf5768010b5586cf9890f62a0260401c5b6708000000000000008216156124ee576801059b0d31585743ae0260401c5b67040000000000000082161561250d57680102c9a3e778060ee70260401c5b67020000000000000082161561252c5768010163da9fb33356d80260401c5b67010000000000000082161561254b57680100b1afa5abcbed610260401c5b66ff00000000000082161561264a5766800000000000008216156125785768010058c86da1c09ea20260401c5b6640000000000000821615612596576801002c605e2e8cec500260401c5b66200000000000008216156125b457680100162f3904051fa10260401c5b66100000000000008216156125d2576801000b175effdc76ba0260401c5b66080000000000008216156125f057680100058ba01fb9f96d0260401c5b660400000000000082161561260e5768010002c5cc37da94920260401c5b660200000000000082161561262c576801000162e525ee05470260401c5b660100000000000082161561264a5768010000b17255775c040260401c5b65ff00000000008216156127405765800000000000821615612675576801000058b91b5bc9ae0260401c5b6540000000000082161561269257680100002c5c89d5ec6d0260401c5b652000000000008216156126af5768010000162e43f4f8310260401c5b651000000000008216156126cc57680100000b1721bcfc9a0260401c5b650800000000008216156126e95768010000058b90cf1e6e0260401c5b65040000000000821615612706576801000002c5c863b73f0260401c5b6502000000000082161561272357680100000162e430e5a20260401c5b65010000000000821615612740576801000000b1721835510260401c5b64ff0000000082161561282d5764800000000082161561276957680100000058b90c0b490260401c5b6440000000008216156127855768010000002c5c8601cc0260401c5b6420000000008216156127a1576801000000162e42fff00260401c5b6410000000008216156127bd5768010000000b17217fbb0260401c5b6408000000008216156127d9576801000000058b90bfce0260401c5b6404000000008216156127f557680100000002c5c85fe30260401c5b6402000000008216156128115768010000000162e42ff10260401c5b64010000000082161561282d57680100000000b17217f80260401c5b63ff0000008216156129115763800000008216156128545768010000000058b90bfc0260401c5b634000000082161561286f576801000000002c5c85fe0260401c5b632000000082161561288a57680100000000162e42ff0260401c5b63100000008216156128a5576801000000000b17217f0260401c5b63080000008216156128c057680100000000058b90c00260401c5b63040000008216156128db5768010000000002c5c8600260401c5b63020000008216156128f6576801000000000162e4300260401c5b63010000008216156129115768010000000000b172180260401c5b62ff00008216156129ec5762800000821615612936576801000000000058b90c0260401c5b6240000082161561295057680100000000002c5c860260401c5b6220000082161561296a5768010000000000162e430260401c5b6210000082161561298457680100000000000b17210260401c5b6208000082161561299e5768010000000000058b910260401c5b620400008216156129b8576801000000000002c5c80260401c5b620200008216156129d257680100000000000162e40260401c5b620100008216156129ec576801000000000000b1720260401c5b61ff00821615612abe57618000821615612a0f57680100000000000058b90260401c5b614000821615612a285768010000000000002c5d0260401c5b612000821615612a41576801000000000000162e0260401c5b611000821615612a5a5768010000000000000b170260401c5b610800821615612a73576801000000000000058c0260401c5b610400821615612a8c57680100000000000002c60260401c5b610200821615612aa557680100000000000001630260401c5b610100821615612abe57680100000000000000b10260401c5b60ff821615612b87576080821615612adf57680100000000000000590260401c5b6040821615612af7576801000000000000002c0260401c5b6020821615612b0f57680100000000000000160260401c5b6010821615612b27576801000000000000000b0260401c5b6008821615612b3f57680100000000000000060260401c5b6004821615612b5757680100000000000000030260401c5b6002821615612b6f57680100000000000000010260401c5b6001821615612b8757680100000000000000010260401c5b670de0b6b3a76400000260409190911c60bf031c90565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610b4a6020830184612b9e565b5f60208284031215612bee575f5ffd5b5035919050565b80356001600160a01b0381168114612c0b575f5ffd5b919050565b5f5f60408385031215612c21575f5ffd5b612c2a83612bf5565b946020939093013593505050565b5f5f5f60608486031215612c4a575f5ffd5b505081359360208301359350604090920135919050565b5f5f5f60608486031215612c73575f5ffd5b612c7c84612bf5565b9250612c8a60208501612bf5565b929592945050506040919091013590565b5f60208284031215612cab575f5ffd5b610b4a82612bf5565b803560ff81168114612c0b575f5ffd5b5f5f5f5f5f60a08688031215612cd8575f5ffd5b612ce186612bf5565b945060208601359350612cf660408701612cb4565b94979396509394606081013594506080013592915050565b5f5f60408385031215612d1f575f5ffd5b82359150612d2f60208401612bf5565b90509250929050565b5f5f5f5f5f5f5f60e0888a031215612d4e575f5ffd5b87359650612d5e60208901612bf5565b95506040880135945060608801358015158114612d79575f5ffd5b9350612d8760808901612cb4565b9699959850939692959460a0840135945060c09093013592915050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112612dc7575f5ffd5b813567ffffffffffffffff811115612de157612de1612da4565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715612e1057612e10612da4565b604052818152838201602001851015612e27575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f5f5f60e0888a031215612e59575f5ffd5b612e6288612bf5565b9650612e7060208901612bf5565b955060408801359450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff811115612ea7575f5ffd5b612eb38a828b01612db8565b91505092959891949750929550565b5f5f5f5f5f60a08688031215612ed6575f5ffd5b612edf86612bf5565b9450612eed60208701612bf5565b93506040860135925060608601359150608086013567ffffffffffffffff811115612f16575f5ffd5b612f2288828901612db8565b9150509295509295909350565b5f5f5f60608486031215612f41575f5ffd5b83359250612f5160208501612bf5565b9150612f5f60408501612bf5565b90509250925092565b5f5f5f60608486031215612f7a575f5ffd5b612f8384612bf5565b925060208401359150604084013567ffffffffffffffff811115612fa5575f5ffd5b612fb186828701612db8565b9150509250925092565b5f5f5f5f5f5f5f60e0888a031215612fd1575f5ffd5b612fda88612bf5565b9650612fe860208901612bf5565b95506040880135945060608801359350612d8760808901612cb4565b5f5f60408385031215613015575f5ffd5b61301e83612bf5565b9150612d2f60208401612bf5565b5f5f5f5f5f5f5f5f5f6101208a8c031215613045575f5ffd5b61304e8a612bf5565b985061305c60208b01612bf5565b975060408a0135965060608a0135955060808a0135945060a08a0135935061308660c08b01612cb4565b989b979a50959894979396929550929360e081013593506101000135919050565b600181811c908216806130bb57607f821691505b6020821081036130d957634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610bb757610bb76130df565b634e487b7160e01b5f52603260045260245ffd5b928352602083019190915260f81b6001600160f81b031916604082015260410190565b80820180821115610bb757610bb76130df565b634e487b7160e01b5f52601260045260245ffd5b5f6001600160d81b0383168061317c5761317c613150565b6001600160d81b03929092169190910492915050565b9687526001600160a01b0395861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b8082028115828204841417610bb757610bb76130df565b5f826131f3576131f3613150565b500490565b5f5f83545f8160011c9050600182168061321357607f821691505b60208210810361323157634e487b7160e01b5f52602260045260245ffd5b808015613245576001811461325a57613288565b60ff1984168752821515830287019450613288565b5f888152602090205f5b8481101561328057815489820152600190910190602001613264565b505082870194505b50929695505050505050565b5f600182016132a5576132a56130df565b5060010190565b634e487b7160e01b5f52602160045260245ffd5b828152604060208201525f610fc96040830184612b9e565b5f82518060208501845e5f920191825250919050565b5f602082840312156132fe575f5ffd5b505191905056fe6607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000cacd6fd266af91b8aed52accc382b4e165586e29","name":"SfrxUSD","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"prague","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"src/contracts/shared/core/modules/PermitModule.sol","source_code":"pragma solidity ^0.8.0;\n\nimport { SignatureModule } from \"./SignatureModule.sol\";\n\n/// @dev Ripped from OZ 4.9.4 ERC20Permit.sol with namespaced storage and support of ERC1271 signatures\nabstract contract PermitModule is SignatureModule {\n    //==============================================================================\n    // Storage\n    //==============================================================================\n\n    bytes32 private constant PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    //==============================================================================\n    // Functions\n    //==============================================================================\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        permit({\n            owner: owner,\n            spender: spender,\n            value: value,\n            deadline: deadline,\n            signature: abi.encodePacked(r, s, v)\n        });\n    }\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        bytes memory signature\n    ) public virtual {\n        require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n        _requireIsValidSignatureNow({\n            signer: owner,\n            structHash: keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, __useNonce(owner), deadline)),\n            signature: signature\n        });\n\n        __approve(owner, spender, value);\n    }\n\n    //==============================================================================\n    // Virtual methods to override in child class\n    //==============================================================================\n\n    function __approve(address owner, address spender, uint256 amount) internal virtual;\n\n    function __domainSeparatorV4() internal view virtual returns (bytes32);\n\n    function __useNonce(address owner) internal virtual returns (uint256);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/utils/Context.sol","source_code":"// 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"},{"file_path":"node_modules/@prb/math/src/sd59x18/Math.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n    uEXP_MAX_INPUT,\n    uEXP2_MAX_INPUT,\n    uEXP_MIN_THRESHOLD,\n    uEXP2_MIN_THRESHOLD,\n    uHALF_UNIT,\n    uLOG2_10,\n    uLOG2_E,\n    uMAX_SD59x18,\n    uMAX_WHOLE_SD59x18,\n    uMIN_SD59x18,\n    uMIN_WHOLE_SD59x18,\n    UNIT,\n    uUNIT,\n    uUNIT_SQUARED,\n    ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x > MIN_SD59x18.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @return result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt == uMIN_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n    }\n    result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n\n    unchecked {\n        // This operation is equivalent to `x / 2 +  y / 2`, and it can never overflow.\n        int256 sum = (xInt >> 1) + (yInt >> 1);\n\n        if (sum < 0) {\n            // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n            // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n            assembly (\"memory-safe\") {\n                result := add(sum, and(or(xInt, yInt), 1))\n            }\n        } else {\n            // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n            result = wrap(sum + (xInt & yInt & 1));\n        }\n    }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x ≤ MAX_WHOLE_SD59x18\n///\n/// @param x The SD59x18 number to ceil.\n/// @return result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt > uMAX_WHOLE_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n    }\n\n    int256 remainder = xInt % uUNIT;\n    if (remainder == 0) {\n        result = x;\n    } else {\n        unchecked {\n            // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n            int256 resultInt = xInt - remainder;\n            if (xInt > 0) {\n                resultInt += uUNIT;\n            }\n            result = wrap(resultInt);\n        }\n    }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @return result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n    if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x and y.\n    uint256 xAbs;\n    uint256 yAbs;\n    unchecked {\n        xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n        yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n    }\n\n    // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n    uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n    if (resultAbs > uint256(uMAX_SD59x18)) {\n        revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n    }\n\n    // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n    // negative, 0 for positive or zero).\n    bool sameSign = (xInt ^ yInt) > -1;\n\n    // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n    unchecked {\n        result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n    }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x < 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n\n    // Any input less than the threshold returns zero.\n    // This check also prevents an overflow for very small numbers.\n    if (xInt < uEXP_MIN_THRESHOLD) {\n        return ZERO;\n    }\n\n    // This check prevents values greater than 192e18 from being passed to {exp2}.\n    if (xInt > uEXP_MAX_INPUT) {\n        revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n    }\n\n    unchecked {\n        // Inline the fixed-point multiplication to save gas.\n        int256 doubleUnitProduct = xInt * uLOG2_E;\n        result = exp2(wrap(doubleUnitProduct / uUNIT));\n    }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x < -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x < 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < 0) {\n        // The inverse of any number less than the threshold is truncated to zero.\n        if (xInt < uEXP2_MIN_THRESHOLD) {\n            return ZERO;\n        }\n\n        unchecked {\n            // Inline the fixed-point inversion to save gas.\n            result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n        }\n    } else {\n        // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n        if (xInt > uEXP2_MAX_INPUT) {\n            revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n        }\n\n        unchecked {\n            // Convert x to the 192.64-bit fixed-point format.\n            uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n            // It is safe to cast the result to int256 due to the checks above.\n            result = wrap(int256(Common.exp2(x_192x64)));\n        }\n    }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x ≥ MIN_WHOLE_SD59x18\n///\n/// @param x The SD59x18 number to floor.\n/// @return result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < uMIN_WHOLE_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n    }\n\n    int256 remainder = xInt % uUNIT;\n    if (remainder == 0) {\n        result = x;\n    } else {\n        unchecked {\n            // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n            int256 resultInt = xInt - remainder;\n            if (xInt < 0) {\n                resultInt -= uUNIT;\n            }\n            result = wrap(resultInt);\n        }\n    }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @return result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n    if (xInt == 0 || yInt == 0) {\n        return ZERO;\n    }\n\n    unchecked {\n        // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n        int256 xyInt = xInt * yInt;\n        if (xyInt / xInt != yInt) {\n            revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n        }\n\n        // The product must not be negative, since complex numbers are not supported.\n        if (xyInt < 0) {\n            revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n        }\n\n        // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n        // during multiplication. See the comments in {Common.sqrt}.\n        uint256 resultUint = Common.sqrt(uint256(xyInt));\n        result = wrap(int256(resultUint));\n    }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n    // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n    // {log2} can return is ~195_205294292027477728.\n    result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < 0) {\n        revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n    }\n\n    // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n    // prettier-ignore\n    assembly (\"memory-safe\") {\n        switch x\n        case 1 { result := mul(uUNIT, sub(0, 18)) }\n        case 10 { result := mul(uUNIT, sub(1, 18)) }\n        case 100 { result := mul(uUNIT, sub(2, 18)) }\n        case 1000 { result := mul(uUNIT, sub(3, 18)) }\n        case 10000 { result := mul(uUNIT, sub(4, 18)) }\n        case 100000 { result := mul(uUNIT, sub(5, 18)) }\n        case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n        case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n        case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n        case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n        case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n        case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n        case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n        case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n        case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n        case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n        case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n        case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n        case 1000000000000000000 { result := 0 }\n        case 10000000000000000000 { result := uUNIT }\n        case 100000000000000000000 { result := mul(uUNIT, 2) }\n        case 1000000000000000000000 { result := mul(uUNIT, 3) }\n        case 10000000000000000000000 { result := mul(uUNIT, 4) }\n        case 100000000000000000000000 { result := mul(uUNIT, 5) }\n        case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n        case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n        case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n        case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n        case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n        case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n        case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n        case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n        case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n        case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n        case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n        case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n        case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n        case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n        case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n        case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n        case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n        case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n        case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n        case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n        case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n        case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n        case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n        case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n        case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n        case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n        case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n        case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n        case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n        case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n        case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n        case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n        case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n        case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n        case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n        case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n        case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n        case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n        case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n        case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n        case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n        case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n        default { result := uMAX_SD59x18 }\n    }\n\n    if (result.unwrap() == uMAX_SD59x18) {\n        unchecked {\n            // Inline the fixed-point division to save gas.\n            result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n        }\n    }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x > 0\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt <= 0) {\n        revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n    }\n\n    unchecked {\n        int256 sign;\n        if (xInt >= uUNIT) {\n            sign = 1;\n        } else {\n            sign = -1;\n            // Inline the fixed-point inversion to save gas.\n            xInt = uUNIT_SQUARED / xInt;\n        }\n\n        // Calculate the integer part of the logarithm.\n        uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n        // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n        // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n        int256 resultInt = int256(n) * uUNIT;\n\n        // Calculate $y = x * 2^{-n}$.\n        int256 y = xInt >> n;\n\n        // If y is the unit number, the fractional part is zero.\n        if (y == uUNIT) {\n            return wrap(resultInt * sign);\n        }\n\n        // Calculate the fractional part via the iterative approximation.\n        // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n        int256 DOUBLE_UNIT = 2e18;\n        for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n            y = (y * y) / uUNIT;\n\n            // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n            if (y >= DOUBLE_UNIT) {\n                // Add the 2^{-m} factor to the logarithm.\n                resultInt = resultInt + delta;\n\n                // Halve y, which corresponds to z/2 in the Wikipedia article.\n                y >>= 1;\n            }\n        }\n        resultInt *= sign;\n        result = wrap(resultInt);\n    }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n    if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x and y.\n    uint256 xAbs;\n    uint256 yAbs;\n    unchecked {\n        xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n        yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n    }\n\n    // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n    uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n    if (resultAbs > uint256(uMAX_SD59x18)) {\n        revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n    }\n\n    // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n    // negative, 0 for positive or zero).\n    bool sameSign = (xInt ^ yInt) > -1;\n\n    // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n    unchecked {\n        result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n    }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n\n    // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n    if (xInt == 0) {\n        return yInt == 0 ? UNIT : ZERO;\n    }\n    // If x is `UNIT`, the result is always `UNIT`.\n    else if (xInt == uUNIT) {\n        return UNIT;\n    }\n\n    // If y is zero, the result is always `UNIT`.\n    if (yInt == 0) {\n        return UNIT;\n    }\n    // If y is `UNIT`, the result is always x.\n    else if (yInt == uUNIT) {\n        return x;\n    }\n\n    // Calculate the result using the formula.\n    result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n    uint256 xAbs = uint256(abs(x).unwrap());\n\n    // Calculate the first iteration of the loop in advance.\n    uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n    // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n    uint256 yAux = y;\n    for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n        xAbs = Common.mulDiv18(xAbs, xAbs);\n\n        // Equivalent to `y % 2 == 1`.\n        if (yAux & 1 > 0) {\n            resultAbs = Common.mulDiv18(resultAbs, xAbs);\n        }\n    }\n\n    // The result must fit in SD59x18.\n    if (resultAbs > uint256(uMAX_SD59x18)) {\n        revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n    }\n\n    unchecked {\n        // Is the base negative and the exponent odd? If yes, the result should be negative.\n        int256 resultInt = int256(resultAbs);\n        bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n        if (isNegative) {\n            resultInt = -resultInt;\n        }\n        result = wrap(resultInt);\n    }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x ≥ 0, since complex numbers are not supported.\n/// - x ≤ MAX_SD59x18 / UNIT\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < 0) {\n        revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n    }\n    if (xInt > uMAX_SD59x18 / uUNIT) {\n        revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n    }\n\n    unchecked {\n        // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n        // In this case, the two numbers are both the square root.\n        uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n        result = wrap(int256(resultUint));\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/ud2x18/ValueType.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD59x18,\n    Casting.intoUD60x18,\n    Casting.intoUint128,\n    Casting.intoUint256,\n    Casting.intoUint40,\n    Casting.unwrap\n} for UD2x18 global;\n"},{"file_path":"node_modules/@prb/math/src/sd1x18/Constants.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The minimum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n"},{"file_path":"node_modules/@prb/math/src/ud2x18/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\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"},{"file_path":"node_modules/solmate/src/tokens/ERC20.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n    /*//////////////////////////////////////////////////////////////\n                                 EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n    /*//////////////////////////////////////////////////////////////\n                            METADATA STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    string public name;\n\n    string public symbol;\n\n    uint8 public immutable decimals;\n\n    /*//////////////////////////////////////////////////////////////\n                              ERC20 STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 public totalSupply;\n\n    mapping(address => uint256) public balanceOf;\n\n    mapping(address => mapping(address => uint256)) public allowance;\n\n    /*//////////////////////////////////////////////////////////////\n                            EIP-2612 STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal immutable INITIAL_CHAIN_ID;\n\n    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n    mapping(address => uint256) public nonces;\n\n    /*//////////////////////////////////////////////////////////////\n                               CONSTRUCTOR\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(\n        string memory _name,\n        string memory _symbol,\n        uint8 _decimals\n    ) {\n        name = _name;\n        symbol = _symbol;\n        decimals = _decimals;\n\n        INITIAL_CHAIN_ID = block.chainid;\n        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                               ERC20 LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function approve(address spender, uint256 amount) public virtual returns (bool) {\n        allowance[msg.sender][spender] = amount;\n\n        emit Approval(msg.sender, spender, amount);\n\n        return true;\n    }\n\n    function transfer(address to, uint256 amount) public virtual returns (bool) {\n        balanceOf[msg.sender] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(msg.sender, to, amount);\n\n        return true;\n    }\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) public virtual returns (bool) {\n        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n        balanceOf[from] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        return true;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                             EIP-2612 LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n        // Unchecked because the only math done is incrementing\n        // the owner's nonce which cannot realistically overflow.\n        unchecked {\n            address recoveredAddress = ecrecover(\n                keccak256(\n                    abi.encodePacked(\n                        \"\\x19\\x01\",\n                        DOMAIN_SEPARATOR(),\n                        keccak256(\n                            abi.encode(\n                                keccak256(\n                                    \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n                                ),\n                                owner,\n                                spender,\n                                value,\n                                nonces[owner]++,\n                                deadline\n                            )\n                        )\n                    )\n                ),\n                v,\n                r,\n                s\n            );\n\n            require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n            allowance[recoveredAddress][spender] = value;\n        }\n\n        emit Approval(owner, spender, value);\n    }\n\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n    }\n\n    function computeDomainSeparator() internal view virtual returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n                    keccak256(bytes(name)),\n                    keccak256(\"1\"),\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        INTERNAL MINT/BURN LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function _mint(address to, uint256 amount) internal virtual {\n        totalSupply += amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(address(0), to, amount);\n    }\n\n    function _burn(address from, uint256 amount) internal virtual {\n        balanceOf[from] -= amount;\n\n        // Cannot underflow because a user's balance\n        // will never be larger than the total supply.\n        unchecked {\n            totalSupply -= amount;\n        }\n\n        emit Transfer(from, address(0), amount);\n    }\n}\n"},{"file_path":"node_modules/frax-standard-solidity/src/access-control/v2/Timelock2Step.sol","source_code":"// SPDX-License-Identifier: ISC\npragma solidity >=0.8.0;\n\n// ====================================================================\n// |     ______                   _______                             |\n// |    / _____________ __  __   / ____(_____  ____ _____  ________   |\n// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \\/ __ `/ __ \\/ ___/ _ \\  |\n// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |\n// | /_/   /_/   \\__,_/_/|_|  /_/   /_/_/ /_/\\__,_/_/ /_/\\___/\\___/   |\n// |                                                                  |\n// ====================================================================\n// ========================== Timelock2Step ===========================\n// ====================================================================\n// Frax Finance: https://github.com/FraxFinance\n\n// Primary Author\n// Drake Evans: https://github.com/DrakeEvans\n\n// Reviewers\n// Dennis: https://github.com/denett\n\n// ====================================================================\n\n/// @title Timelock2Step\n/// @author Drake Evans (Frax Finance) https://github.com/drakeevans\n/// @dev Inspired by OpenZeppelin's Ownable2Step contract\n/// @notice  An abstract contract which contains 2-step transfer and renounce logic for a timelock address\nabstract contract Timelock2Step {\n    /// @notice The pending timelock address\n    address public pendingTimelockAddress;\n\n    /// @notice The current timelock address\n    address public timelockAddress;\n\n    constructor(address _timelockAddress) {\n        timelockAddress = _timelockAddress;\n    }\n\n    // ============================================================================================\n    // Functions: External Functions\n    // ============================================================================================\n\n    /// @notice The ```transferTimelock``` function initiates the timelock transfer\n    /// @dev Must be called by the current timelock\n    /// @param _newTimelock The address of the nominated (pending) timelock\n    function transferTimelock(address _newTimelock) external virtual {\n        _requireSenderIsTimelock();\n        _transferTimelock(_newTimelock);\n    }\n\n    /// @notice The ```acceptTransferTimelock``` function completes the timelock transfer\n    /// @dev Must be called by the pending timelock\n    function acceptTransferTimelock() external virtual {\n        _requireSenderIsPendingTimelock();\n        _acceptTransferTimelock();\n    }\n\n    /// @notice The ```renounceTimelock``` function renounces the timelock after setting pending timelock to current timelock\n    /// @dev Pending timelock must be set to current timelock before renouncing, creating a 2-step renounce process\n    function renounceTimelock() external virtual {\n        _requireSenderIsTimelock();\n        _requireSenderIsPendingTimelock();\n        _transferTimelock(address(0));\n        _setTimelock(address(0));\n    }\n\n    // ============================================================================================\n    // Functions: Internal Actions\n    // ============================================================================================\n\n    /// @notice The ```_transferTimelock``` function initiates the timelock transfer\n    /// @dev This function is to be implemented by a public function\n    /// @param _newTimelock The address of the nominated (pending) timelock\n    function _transferTimelock(address _newTimelock) internal {\n        pendingTimelockAddress = _newTimelock;\n        emit TimelockTransferStarted(timelockAddress, _newTimelock);\n    }\n\n    /// @notice The ```_acceptTransferTimelock``` function completes the timelock transfer\n    /// @dev This function is to be implemented by a public function\n    function _acceptTransferTimelock() internal {\n        pendingTimelockAddress = address(0);\n        _setTimelock(msg.sender);\n    }\n\n    /// @notice The ```_setTimelock``` function sets the timelock address\n    /// @dev This function is to be implemented by a public function\n    /// @param _newTimelock The address of the new timelock\n    function _setTimelock(address _newTimelock) internal {\n        emit TimelockTransferred(timelockAddress, _newTimelock);\n        timelockAddress = _newTimelock;\n    }\n\n    // ============================================================================================\n    // Functions: Internal Checks\n    // ============================================================================================\n\n    /// @notice The ```_isTimelock``` function checks if _address is current timelock address\n    /// @param _address The address to check against the timelock\n    /// @return Whether or not msg.sender is current timelock address\n    function _isTimelock(address _address) internal view returns (bool) {\n        return _address == timelockAddress;\n    }\n\n    /// @notice The ```_requireIsTimelock``` function reverts if _address is not current timelock address\n    /// @param _address The address to check against the timelock\n    function _requireIsTimelock(address _address) internal view {\n        if (!_isTimelock(_address)) revert AddressIsNotTimelock(timelockAddress, _address);\n    }\n\n    /// @notice The ```_requireSenderIsTimelock``` function reverts if msg.sender is not current timelock address\n    /// @dev This function is to be implemented by a public function\n    function _requireSenderIsTimelock() internal view {\n        _requireIsTimelock(msg.sender);\n    }\n\n    /// @notice The ```_isPendingTimelock``` function checks if the _address is pending timelock address\n    /// @dev This function is to be implemented by a public function\n    /// @param _address The address to check against the pending timelock\n    /// @return Whether or not _address is pending timelock address\n    function _isPendingTimelock(address _address) internal view returns (bool) {\n        return _address == pendingTimelockAddress;\n    }\n\n    /// @notice The ```_requireIsPendingTimelock``` function reverts if the _address is not pending timelock address\n    /// @dev This function is to be implemented by a public function\n    /// @param _address The address to check against the pending timelock\n    function _requireIsPendingTimelock(address _address) internal view {\n        if (!_isPendingTimelock(_address)) revert AddressIsNotPendingTimelock(pendingTimelockAddress, _address);\n    }\n\n    /// @notice The ```_requirePendingTimelock``` function reverts if msg.sender is not pending timelock address\n    /// @dev This function is to be implemented by a public function\n    function _requireSenderIsPendingTimelock() internal view {\n        _requireIsPendingTimelock(msg.sender);\n    }\n\n    // ============================================================================================\n    // Functions: Events\n    // ============================================================================================\n\n    /// @notice The ```TimelockTransferStarted``` event is emitted when the timelock transfer is initiated\n    /// @param previousTimelock The address of the previous timelock\n    /// @param newTimelock The address of the new timelock\n    event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);\n\n    /// @notice The ```TimelockTransferred``` event is emitted when the timelock transfer is completed\n    /// @param previousTimelock The address of the previous timelock\n    /// @param newTimelock The address of the new timelock\n    event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);\n\n    // ============================================================================================\n    // Functions: Errors\n    // ============================================================================================\n\n    /// @notice Emitted when timelock is transferred\n    error AddressIsNotTimelock(address timelockAddress, address actualAddress);\n\n    /// @notice Emitted when pending timelock is transferred\n    error AddressIsNotPendingTimelock(address pendingTimelockAddress, address actualAddress);\n}\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/Constants.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/interfaces/draft-IERC6093.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\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"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/token/ERC20/ERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * Both values are immutable: they can only be set once during construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance < type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/sd1x18/ValueType.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD59x18,\n    Casting.intoUD60x18,\n    Casting.intoUint128,\n    Casting.intoUint256,\n    Casting.intoUint40,\n    Casting.unwrap\n} for SD1x18 global;\n"},{"file_path":"node_modules/@prb/math/src/sd1x18/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast an SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast an SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast an SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast an SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast an SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n"},{"file_path":"node_modules/solmate/src/utils/SafeTransferLib.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.\n/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n    /*//////////////////////////////////////////////////////////////\n                             ETH OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function safeTransferETH(address to, uint256 amount) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer the ETH and store if it succeeded or not.\n            success := call(gas(), to, amount, 0, 0, 0, 0)\n        }\n\n        require(success, \"ETH_TRANSFER_FAILED\");\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            ERC20 OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function safeTransferFrom(\n        ERC20 token,\n        address from,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"from\" argument.\n            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n            mstore(add(freeMemoryPointer, 68), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)\n            )\n        }\n\n        require(success, \"TRANSFER_FROM_FAILED\");\n    }\n\n    function safeTransfer(\n        ERC20 token,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n            mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n            )\n        }\n\n        require(success, \"TRANSFER_FAILED\");\n    }\n\n    function safeApprove(\n        ERC20 token,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n            mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n            )\n        }\n\n        require(success, \"APPROVE_FAILED\");\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/Casting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD21x18 } from \"../sd21x18/Constants.sol\";\nimport { SD21x18 } from \"../sd21x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { uMAX_UD21x18 } from \"../ud21x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD21x18 } from \"../ud21x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x ≤ uMAX_SD1x18\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uint256(int256(uMAX_SD1x18))) {\n        revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n    }\n    result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into SD21x18.\n/// @dev Requirements:\n/// - x ≤ uMAX_SD21x18\nfunction intoSD21x18(UD60x18 x) pure returns (SD21x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uint256(int256(uMAX_SD21x18))) {\n        revert CastingErrors.PRBMath_UD60x18_IntoSD21x18_Overflow(x);\n    }\n    result = SD21x18.wrap(int128(uint128(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x ≤ uMAX_UD2x18\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uMAX_UD2x18) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n    }\n    result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into UD21x18.\n/// @dev Requirements:\n/// - x ≤ uMAX_UD21x18\nfunction intoUD21x18(UD60x18 x) pure returns (UD21x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uMAX_UD21x18) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUD21x18_Overflow(x);\n    }\n    result = UD21x18.wrap(uint128(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x ≤ uMAX_SD59x18\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uint256(uMAX_SD59x18)) {\n        revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n    }\n    result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n    result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x ≤ MAX_UINT128\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > MAX_UINT128) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n    }\n    result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x ≤ MAX_UINT40\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > MAX_UINT40) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n    result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(x);\n}\n"},{"file_path":"node_modules/@prb/math/src/ud21x18/Constants.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD21x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD21x18 number.\nUD21x18 constant E = UD21x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD21x18 number can have.\nuint128 constant uMAX_UD21x18 = 340282366920938463463_374607431768211455;\nUD21x18 constant MAX_UD21x18 = UD21x18.wrap(uMAX_UD21x18);\n\n/// @dev PI as a UD21x18 number.\nUD21x18 constant PI = UD21x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD21x18.\nuint256 constant uUNIT = 1e18;\nUD21x18 constant UNIT = UD21x18.wrap(1e18);\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD21x18.\nerror PRBMath_UD60x18_IntoSD21x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD21x18.\nerror PRBMath_UD60x18_IntoUD21x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than UNIT.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/Conversions.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n    result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x ≤ MAX_UD60x18 / UNIT\n///\n/// @param x The basic integer to convert.\n/// @return result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n    if (x > uMAX_UD60x18 / uUNIT) {\n        revert PRBMath_UD60x18_Convert_Overflow(x);\n    }\n    unchecked {\n        result = UD60x18.wrap(x * uUNIT);\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/sd21x18/Casting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD21x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD21x18 number into SD59x18.\n/// @dev There is no overflow check because SD21x18 ⊆ SD59x18.\nfunction intoSD59x18(SD21x18 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(int256(SD21x18.unwrap(x)));\n}\n\n/// @notice Casts an SD21x18 number into UD60x18.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUD60x18(SD21x18 x) pure returns (UD60x18 result) {\n    int128 xInt = SD21x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD21x18_ToUD60x18_Underflow(x);\n    }\n    result = UD60x18.wrap(uint128(xInt));\n}\n\n/// @notice Casts an SD21x18 number into uint128.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUint128(SD21x18 x) pure returns (uint128 result) {\n    int128 xInt = SD21x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD21x18_ToUint128_Underflow(x);\n    }\n    result = uint128(xInt);\n}\n\n/// @notice Casts an SD21x18 number into uint256.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUint256(SD21x18 x) pure returns (uint256 result) {\n    int128 xInt = SD21x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD21x18_ToUint256_Underflow(x);\n    }\n    result = uint256(uint128(xInt));\n}\n\n/// @notice Casts an SD21x18 number into uint40.\n/// @dev Requirements:\n/// - x ≥ 0\n/// - x ≤ MAX_UINT40\nfunction intoUint40(SD21x18 x) pure returns (uint40 result) {\n    int128 xInt = SD21x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD21x18_ToUint40_Underflow(x);\n    }\n    if (xInt > int128(uint128(Common.MAX_UINT40))) {\n        revert CastingErrors.PRBMath_SD21x18_ToUint40_Overflow(x);\n    }\n    result = uint40(uint128(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd21x18(int128 x) pure returns (SD21x18 result) {\n    result = SD21x18.wrap(x);\n}\n\n/// @notice Unwraps an SD21x18 number into int128.\nfunction unwrap(SD21x18 x) pure returns (int128 result) {\n    result = SD21x18.unwrap(x);\n}\n\n/// @notice Wraps an int128 number into SD21x18.\nfunction wrap(int128 x) pure returns (SD21x18 result) {\n    result = SD21x18.wrap(x);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/utils/cryptography/SignatureChecker.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.20;\n\nimport {ECDSA} from \"./ECDSA.sol\";\nimport {IERC1271} from \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC-1271 signatures from smart contract wallets like\n * Argent and Safe Wallet (previously Gnosis Safe).\n */\nlibrary SignatureChecker {\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n     * signature is validated against that smart contract using ERC-1271, otherwise it's validated using `ECDSA.recover`.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n        if (signer.code.length == 0) {\n            (address recovered, ECDSA.RecoverError err, ) = ECDSA.tryRecover(hash, signature);\n            return err == ECDSA.RecoverError.NoError && recovered == signer;\n        } else {\n            return isValidERC1271SignatureNow(signer, hash, signature);\n        }\n    }\n\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n     * against the signer smart contract using ERC-1271.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidERC1271SignatureNow(\n        address signer,\n        bytes32 hash,\n        bytes memory signature\n    ) internal view returns (bool) {\n        (bool success, bytes memory result) = signer.staticcall(\n            abi.encodeCall(IERC1271.isValidSignature, (hash, signature))\n        );\n        return (success &&\n            result.length >= 32 &&\n            abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n    }\n}\n"},{"file_path":"src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD3.sol","source_code":"pragma solidity ^0.8.21;\n\n// ====================================================================\n// |     ______                   _______                             |\n// |    / _____________ __  __   / ____(_____  ____ _____  ________   |\n// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \\/ __ `/ __ \\/ ___/ _ \\  |\n// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |\n// | /_/   /_/   \\__,_/_/|_|  /_/   /_/_/ /_/\\__,_/_/ /_/\\___/\\___/   |\n// |                                                                  |\n// ====================================================================\n//=========================== StakedFrxUSD3 ===========================\n// ====================================================================\n\nimport { IERC20 } from \"@openzeppelin/contracts-5.3.0/token/ERC20/IERC20.sol\";\nimport { ERC20 } from \"solmate/tokens/ERC20.sol\";\n\nimport { SfrxUSD2 } from \"src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD2.sol\";\nimport { EIP3009Module, SignatureModule } from \"src/contracts/shared/core/modules/EIP3009Module.sol\";\nimport { PermitModule } from \"src/contracts/shared/core/modules/PermitModule.sol\";\n\n/**\n * @title StakedFrxUSD3\n * @notice This contract is an upgrade of SfrxUSD2 with EIP-3009, ERC-1271.\n */\ncontract SfrxUSD3 is SfrxUSD2, EIP3009Module, PermitModule {\n    function version() public pure override returns (string memory) {\n        return \"3.0.0\";\n    }\n\n    constructor(address _underlying) SfrxUSD2(IERC20(_underlying), \"Staked Frax USD\", \"sfrxUSD\", address(0)) {}\n\n    /*//////////////////////////////////////////////////////////////\n                        Module Overrides\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev PermitModule override\n    /// @dev solmate ERC20 does not have _approve like OZ: so we create it here\n    function __approve(address owner, address spender, uint256 amount) internal override {\n        allowance[owner][spender] = amount;\n\n        emit Approval(owner, spender, amount);\n    }\n\n    function __transfer(address from, address to, uint256 amount) internal override returns (bool) {\n        balanceOf[from] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n        return true;\n    }\n\n    function __domainSeparatorV4() internal view override(PermitModule) returns (bytes32) {\n        return DOMAIN_SEPARATOR();\n    }\n\n    function __hashTypedDataV4(bytes32 structHash) internal view override(SignatureModule) returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", DOMAIN_SEPARATOR(), structHash));\n    }\n\n    function __useNonce(address owner) internal override(PermitModule) returns (uint256) {\n        return nonces[owner]++;\n    }\n\n    /// @dev Use PermitModule permit() with ERC-1271 support\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public override(ERC20, PermitModule) {\n        return\n            PermitModule.permit({ owner: owner, spender: spender, value: value, deadline: deadline, v: v, r: r, s: s });\n    }\n\n    /// @dev override DOMAIN_SEPARATOR() to utilize the proxy address over the cached implementation address\n    function DOMAIN_SEPARATOR() public view override returns (bytes32) {\n        return computeDomainSeparator();\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/ValueType.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD1x18,\n    Casting.intoSD21x18,\n    Casting.intoSD59x18,\n    Casting.intoUD2x18,\n    Casting.intoUD21x18,\n    Casting.intoUint128,\n    Casting.intoUint256,\n    Casting.intoUint40,\n    Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                            MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n    Math.avg,\n    Math.ceil,\n    Math.div,\n    Math.exp,\n    Math.exp2,\n    Math.floor,\n    Math.frac,\n    Math.gm,\n    Math.inv,\n    Math.ln,\n    Math.log10,\n    Math.log2,\n    Math.mul,\n    Math.pow,\n    Math.powu,\n    Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n    Helpers.add,\n    Helpers.and,\n    Helpers.eq,\n    Helpers.gt,\n    Helpers.gte,\n    Helpers.isZero,\n    Helpers.lshift,\n    Helpers.lt,\n    Helpers.lte,\n    Helpers.mod,\n    Helpers.neq,\n    Helpers.not,\n    Helpers.or,\n    Helpers.rshift,\n    Helpers.sub,\n    Helpers.uncheckedAdd,\n    Helpers.uncheckedSub,\n    Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n    Helpers.add as +,\n    Helpers.and2 as &,\n    Math.div as /,\n    Helpers.eq as ==,\n    Helpers.gt as >,\n    Helpers.gte as >=,\n    Helpers.lt as <,\n    Helpers.lte as <=,\n    Helpers.or as |,\n    Helpers.mod as %,\n    Math.mul as *,\n    Helpers.neq as !=,\n    Helpers.not as ~,\n    Helpers.sub as -,\n    Helpers.xor as ^\n} for UD60x18 global;\n"},{"file_path":"node_modules/@prb/math/src/sd59x18/Casting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD21x18, uMIN_SD21x18 } from \"../sd21x18/Constants.sol\";\nimport { SD21x18 } from \"../sd21x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { uMAX_UD21x18 } from \"../ud21x18/Constants.sol\";\nimport { UD21x18 } from \"../ud21x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n    result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x ≥ uMIN_SD1x18\n/// - x ≤ uMAX_SD1x18\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < uMIN_SD1x18) {\n        revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n    }\n    if (xInt > uMAX_SD1x18) {\n        revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n    }\n    result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into SD21x18.\n/// @dev Requirements:\n/// - x ≥ uMIN_SD21x18\n/// - x ≤ uMAX_SD21x18\nfunction intoSD21x18(SD59x18 x) pure returns (SD21x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < uMIN_SD21x18) {\n        revert CastingErrors.PRBMath_SD59x18_IntoSD21x18_Underflow(x);\n    }\n    if (xInt > uMAX_SD21x18) {\n        revert CastingErrors.PRBMath_SD59x18_IntoSD21x18_Overflow(x);\n    }\n    result = SD21x18.wrap(int128(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x ≥ 0\n/// - x ≤ uMAX_UD2x18\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n    }\n    if (xInt > int256(uint256(uMAX_UD2x18))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n    }\n    result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD21x18.\n/// @dev Requirements:\n/// - x ≥ 0\n/// - x ≤ uMAX_UD21x18\nfunction intoUD21x18(SD59x18 x) pure returns (UD21x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD21x18_Underflow(x);\n    }\n    if (xInt > int256(uint256(uMAX_UD21x18))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD21x18_Overflow(x);\n    }\n    result = UD21x18.wrap(uint128(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n    }\n    result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n    }\n    result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x ≥ 0\n/// - x ≤ uMAX_UINT128\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n    }\n    if (xInt > int256(uint256(MAX_UINT128))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n    }\n    result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x ≥ 0\n/// - x ≤ MAX_UINT40\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n    }\n    if (xInt > int256(uint256(MAX_UINT40))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n    result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(x);\n}\n"},{"file_path":"node_modules/@prb/math/src/sd21x18/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD21x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast an SD21x18 number that doesn't fit in uint128.\nerror PRBMath_SD21x18_ToUint128_Underflow(SD21x18 x);\n\n/// @notice Thrown when trying to cast an SD21x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD21x18_ToUD60x18_Underflow(SD21x18 x);\n\n/// @notice Thrown when trying to cast an SD21x18 number that doesn't fit in uint256.\nerror PRBMath_SD21x18_ToUint256_Underflow(SD21x18 x);\n\n/// @notice Thrown when trying to cast an SD21x18 number that doesn't fit in uint40.\nerror PRBMath_SD21x18_ToUint40_Overflow(SD21x18 x);\n\n/// @notice Thrown when trying to cast an SD21x18 number that doesn't fit in uint40.\nerror PRBMath_SD21x18_ToUint40_Underflow(SD21x18 x);\n"},{"file_path":"node_modules/@prb/math/src/sd59x18/Helpers.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n    return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n    result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() + y.unwrap());\n    }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() - y.unwrap());\n    }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n    unchecked {\n        result = wrap(-x.unwrap());\n    }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() ^ y.unwrap());\n}\n"},{"file_path":"node_modules/@prb/math/src/sd59x18/Constants.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/Helpers.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n    // This wouldn't work if x could be negative.\n    result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n    result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() + y.unwrap());\n    }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() - y.unwrap());\n    }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() ^ y.unwrap());\n}\n"},{"file_path":"node_modules/solmate/src/mixins/ERC4626.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\nimport {SafeTransferLib} from \"../utils/SafeTransferLib.sol\";\nimport {FixedPointMathLib} from \"../utils/FixedPointMathLib.sol\";\n\n/// @notice Minimal ERC4626 tokenized Vault implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol)\nabstract contract ERC4626 is ERC20 {\n    using SafeTransferLib for ERC20;\n    using FixedPointMathLib for uint256;\n\n    /*//////////////////////////////////////////////////////////////\n                                 EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);\n\n    event Withdraw(\n        address indexed caller,\n        address indexed receiver,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /*//////////////////////////////////////////////////////////////\n                               IMMUTABLES\n    //////////////////////////////////////////////////////////////*/\n\n    ERC20 public immutable asset;\n\n    constructor(\n        ERC20 _asset,\n        string memory _name,\n        string memory _symbol\n    ) ERC20(_name, _symbol, _asset.decimals()) {\n        asset = _asset;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        DEPOSIT/WITHDRAWAL LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {\n        // Check for rounding error since we round down in previewDeposit.\n        require((shares = previewDeposit(assets)) != 0, \"ZERO_SHARES\");\n\n        // Need to transfer before minting or ERC777s could reenter.\n        asset.safeTransferFrom(msg.sender, address(this), assets);\n\n        _mint(receiver, shares);\n\n        emit Deposit(msg.sender, receiver, assets, shares);\n\n        afterDeposit(assets, shares);\n    }\n\n    function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {\n        assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.\n\n        // Need to transfer before minting or ERC777s could reenter.\n        asset.safeTransferFrom(msg.sender, address(this), assets);\n\n        _mint(receiver, shares);\n\n        emit Deposit(msg.sender, receiver, assets, shares);\n\n        afterDeposit(assets, shares);\n    }\n\n    function withdraw(\n        uint256 assets,\n        address receiver,\n        address owner\n    ) public virtual returns (uint256 shares) {\n        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.\n\n        if (msg.sender != owner) {\n            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.\n\n            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;\n        }\n\n        beforeWithdraw(assets, shares);\n\n        _burn(owner, shares);\n\n        emit Withdraw(msg.sender, receiver, owner, assets, shares);\n\n        asset.safeTransfer(receiver, assets);\n    }\n\n    function redeem(\n        uint256 shares,\n        address receiver,\n        address owner\n    ) public virtual returns (uint256 assets) {\n        if (msg.sender != owner) {\n            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.\n\n            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;\n        }\n\n        // Check for rounding error since we round down in previewRedeem.\n        require((assets = previewRedeem(shares)) != 0, \"ZERO_ASSETS\");\n\n        beforeWithdraw(assets, shares);\n\n        _burn(owner, shares);\n\n        emit Withdraw(msg.sender, receiver, owner, assets, shares);\n\n        asset.safeTransfer(receiver, assets);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            ACCOUNTING LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function totalAssets() public view virtual returns (uint256);\n\n    function convertToShares(uint256 assets) public view virtual returns (uint256) {\n        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.\n\n        return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());\n    }\n\n    function convertToAssets(uint256 shares) public view virtual returns (uint256) {\n        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.\n\n        return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);\n    }\n\n    function previewDeposit(uint256 assets) public view virtual returns (uint256) {\n        return convertToShares(assets);\n    }\n\n    function previewMint(uint256 shares) public view virtual returns (uint256) {\n        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.\n\n        return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);\n    }\n\n    function previewWithdraw(uint256 assets) public view virtual returns (uint256) {\n        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.\n\n        return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());\n    }\n\n    function previewRedeem(uint256 shares) public view virtual returns (uint256) {\n        return convertToAssets(shares);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                     DEPOSIT/WITHDRAWAL LIMIT LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function maxDeposit(address) public view virtual returns (uint256) {\n        return type(uint256).max;\n    }\n\n    function maxMint(address) public view virtual returns (uint256) {\n        return type(uint256).max;\n    }\n\n    function maxWithdraw(address owner) public view virtual returns (uint256) {\n        return convertToAssets(balanceOf[owner]);\n    }\n\n    function maxRedeem(address owner) public view virtual returns (uint256) {\n        return balanceOf[owner];\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                          INTERNAL HOOKS LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}\n\n    function afterDeposit(uint256 assets, uint256 shares) internal virtual {}\n}\n"},{"file_path":"src/contracts/ethereum/sfrxUSD/inherited/LinearRewardsErc4626_2.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.21;\n\n// ====================================================================\n// |     ______                   _______                             |\n// |    / _____________ __  __   / ____(_____  ____ _____  ________   |\n// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \\/ __ `/ __ \\/ ___/ _ \\  |\n// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |\n// | /_/   /_/   \\__,_/_/|_|  /_/   /_/_/ /_/\\__,_/_/ /_/\\___/\\___/   |\n// |                                                                  |\n// ====================================================================\n// ===================== LinearRewardsErc4626_2 ====================\n// ====================================================================\n// Frax Finance: https://github.com/FraxFinance\n\nimport { ERC20, ERC4626 } from \"solmate/mixins/ERC4626.sol\";\nimport { ln, mul, div, exp, wrap } from \"@prb/math/src/ud60x18/Math.sol\";\nimport { convert } from \"@prb/math/src/ud60x18/Conversions.sol\";\nimport { UD60x18 } from \"@prb/math/src/ud60x18/ValueType.sol\";\n\n/// @title LinearRewardsErc4626\n/// @notice An ERC4626 Vault implementation with linear rewards\nabstract contract LinearRewardsErc4626_2 is ERC4626 {\n    /// @notice The precision of all integer calculations\n    uint256 public constant PRECISION = 1e18;\n\n    /// @notice One year, in seconds\n    uint256 public constant ONE_YEAR = 31_536_000;\n\n    /// @notice The rewards cycle length in seconds\n    uint256 public immutable REWARDS_CYCLE_LENGTH = 604_800; // 7 days\n\n    /// @notice Precomputed year\n    UD60x18 public immutable ONE_YEAR_UD60X18;\n\n    /// @notice Information about the current rewards cycle\n    struct RewardsCycleData {\n        uint40 cycleEnd; // Timestamp of the end of the current rewards cycle\n        uint40 lastSync; // Timestamp of the last time the rewards cycle was synced\n        uint216 rewardCycleAmount; // Amount of rewards to be distributed in the current cycle\n    }\n\n    /// @notice The rewards cycle data, stored in a single word to save gas\n    RewardsCycleData public DEPRECATED__rewardsCycleData;\n\n    /// @notice The timestamp of the last time rewards were distributed\n    uint256 public DEPRECATED__lastRewardsDistribution;\n\n    /// @notice The total amount of assets that have been distributed and deposited\n    uint256 public DEPRECATED__storedTotalAssets;\n\n    /// @notice The precision of the underlying asset\n    uint256 public immutable UNDERLYING_PRECISION;\n\n    // ---------------------------------------------\n    // DEPRECATED STORAGE SLOTS (for storage order preservation)\n    // ---------------------------------------------\n    /// @notice The pending timelock address\n    address public DEPRECATED__pendingTimelockAddress;\n\n    /// @notice The current timelock address\n    address public DEPRECATED__timelockAddress;\n\n    /// @notice The maximum amount of rewards that can be distributed per second per 1e18 asset\n    uint256 public DEPRECATED__maxDistributionPerSecondPerAsset;\n\n    uint256 private DEPRECATED__initializeStage;\n\n    // ---------------------------------------------\n    // NEW STATE VARIABLES\n    // ---------------------------------------------\n\n    /// @notice Last stored pricePerShare. Current rate is stored + (rate * pricePerShareIncPerSecond)\n    uint256 public pricePerShareStored;\n\n    /// @notice Manually set increase in pricePerShare, per second\n    uint256 public pricePerShareIncPerSecond;\n\n    /// @notice The last time the contract was synced\n    uint256 public lastSync;\n\n    // ---------------------------------------------\n    // CONSTRUCTOR\n    // ---------------------------------------------\n\n    /// @param _underlying The erc20 asset deposited\n    /// @param _name The name of the vault\n    /// @param _symbol The symbol of the vault\n    constructor(ERC20 _underlying, string memory _name, string memory _symbol) ERC4626(_underlying, _name, _symbol) {\n        if (_underlying.decimals() != 18) revert UnderlyingAssetMustBe18Decimals();\n        UNDERLYING_PRECISION = 10 ** _underlying.decimals();\n        ONE_YEAR_UD60X18 = convert(ONE_YEAR);\n    }\n\n    // ---------------------------------------------\n    // VIEW FUNCTIONS\n    // ---------------------------------------------\n\n    /// @notice Calculate pricePerShare increase per second needed for a given APY.\n    /// @param _apyE18 APY in 1.%%E18 (e.g. 5% APY = input 1.05e18). Must be >= 1e18\n    /// @return _newPPSIPS The needed pricePerShare increase, per second, in UNDERLYING_PRECISION\n    function calcPPSIPSForGivenAPY(uint256 _apyE18) public view returns (uint256 _newPPSIPS) {\n        if (_apyE18 < 1e18) revert InvalidAPY();\n        // Old\n        // UD60x18 _numerator = mul(ln(convert(_apyE18)), convert(1e18)) - mul(ln(convert(1e18)), convert(1e18));\n        // UD60x18 _denominator = convert(ONE_YEAR);\n        // _newPPSIPS = convert(div(_numerator, _denominator));\n        // New\n        UD60x18 _numerator = ln(wrap(_apyE18));\n        UD60x18 _denominator = ONE_YEAR_UD60X18;\n        _newPPSIPS = (div(_numerator, _denominator)).unwrap();\n    }\n\n    /// @notice Calculate the total assets as of a given time.\n    /// @param _asOfTime The time at which to calculate. Must be now or in the future.\n    /// @return _newTotalAssets Expected total assets at _asOfTime, in UNDERLYING_PRECISION\n    function _previewTotalAssets(uint256 _asOfTime) internal view returns (uint256 _newTotalAssets) {\n        _newTotalAssets = (_previewPricePerShare(_asOfTime) * totalSupply) / 1e18;\n    }\n\n    /// @notice Calculate current totalAssets as of now, accounting for elapsed time\n    /// @return _newTotalAssets Total assets as of right now, in UNDERLYING_PRECISION\n    function previewTotalAssets() public view returns (uint256 _newTotalAssets) {\n        // Do the calculation\n        return _previewTotalAssets(block.timestamp);\n    }\n\n    /// @notice Calculate current totalAssets as of now, accounting for elapsed time\n    /// @return _newTotalAssets Total assets as of right now, in UNDERLYING_PRECISION\n    function storedTotalAssets() public view returns (uint256 _newTotalAssets) {\n        return previewTotalAssets();\n    }\n\n    /// @notice Calculate totalAssets at a future time\n    /// @param _futureTime The future time at which to calculate\n    /// @return _newTotalAssets Expected total assets at _futureTime, in UNDERLYING_PRECISION\n    function previewTotalAssetsFuture(uint256 _futureTime) public view returns (uint256 _newTotalAssets) {\n        // Do the calculation\n        return _previewTotalAssets(_futureTime);\n    }\n\n    /// @notice Calculate current pricePerShare as of the given time, accounting for any elapsed time since the last sync.\n    /// @param _asOfTime The time at which to calculate. Must be now or in the future\n    /// @return _newPricePerShare Expected pricePerShare at _asOfTime, in UNDERLYING_PRECISION\n    function _previewPricePerShare(uint256 _asOfTime) internal view returns (uint256 _newPricePerShare) {\n        // Calculate the elapsed time\n        uint256 _elapsedTime = _asOfTime - lastSync;\n\n        // Continuously compounding interest. Done here instead of in _previewTotalAssets\n        // p(t) = p₀ * e^((dr)*t)\n        // Also might be able to use e^(xy) = (e^x)^y (to avoid overflows)\n        // ---------------------------------------\n        // Calculate e^x and convert back to uint256\n\n        // Get the UD60x18 exponent first and scale down by UNDERLYING_PRECISION\n        // OLD: UD60x18 _exponentUD60_18 = div(\n        //     convert(pricePerShareIncPerSecond * _elapsedTime),\n        //     convert(UNDERLYING_PRECISION)\n        // );\n        // Get the UD60x18 exponent first and scale down by UNDERLYING_PRECISION\n        UD60x18 _exponentUD60_18 = wrap(pricePerShareIncPerSecond * _elapsedTime);\n        // UD60x18 _exponentUD60_18 = div(\n        //     convert(pricePerShareIncPerSecond * _elapsedTime),\n        //     convert(UNDERLYING_PRECISION)\n        // );\n\n        // Get the raw e^exponent in UD60x18\n        UD60x18 _ePowUD60_18 = exp(_exponentUD60_18);\n\n        // Old\n        // {\n        //     // Scale the UD60x18 up by UNDERLYING_PRECISION and convert to uint256\n        //     uint256 _ePowU256 = convert(mul(_ePowUD60_18, convert(UNDERLYING_PRECISION)));\n\n        //     // Calculate _newPricePerShare\n        //     _newPricePerShare = (pricePerShareStored * _ePowU256) / UNDERLYING_PRECISION;\n        // }\n\n        // New\n        {\n            _newPricePerShare = mul(wrap(pricePerShareStored), _ePowUD60_18).unwrap();\n        }\n    }\n\n    /// @notice Calculate current pricePerShare as of now, accounting for any elapsed time since the last sync. Same as pricePerShare().\n    /// @return _newPricePerShare Current pricePerShare, in UNDERLYING_PRECISION\n    function previewPricePerShare() public view returns (uint256 _newPricePerShare) {\n        // Do the calculation\n        return _previewPricePerShare(block.timestamp);\n    }\n\n    /// @notice Calculate pricePerShare at a future time\n    /// @param _futureTime The future time at which to calculate\n    /// @return _newPricePerShare Expected pricePerShare at _asOfTime, in UNDERLYING_PRECISION\n    function previewPricePerShareFuture(uint256 _futureTime) public view returns (uint256 _newPricePerShare) {\n        // Do the calculation\n        return _previewPricePerShare(_futureTime);\n    }\n\n    /// @notice Calculate pricePerShare and totalAssets at a given time\n    /// @param _asOfTime The time at which to calculate. Must be now or in the future.\n    /// @return _pricePerShare Expected pricePerShare at _asOfTime, in UNDERLYING_PRECISION\n    /// @return _totalAssets Expected totalAssets at _asOfTime, in UNDERLYING_PRECISION\n    function _previewPPSAndTotalAssets(\n        uint256 _asOfTime\n    ) internal view returns (uint256 _pricePerShare, uint256 _totalAssets) {\n        _pricePerShare = _previewPricePerShare(_asOfTime);\n        _totalAssets = _previewTotalAssets(_asOfTime);\n    }\n\n    /// @notice Calculate pricePerShare and totalAssets as of right now\n    /// @return _pricePerShare Current pricePerShare, in UNDERLYING_PRECISION\n    /// @return _totalAssets Current totalAssets, in UNDERLYING_PRECISION\n    function previewPPSAndTotalAssets() public view returns (uint256 _pricePerShare, uint256 _totalAssets) {\n        return _previewPPSAndTotalAssets(block.timestamp);\n    }\n\n    /// @notice The current price per share token, in asset tokens. Same as previewPricePerShare().\n    /// @return _pricePerShare Current pricePerShare, in UNDERLYING_PRECISION\n    function pricePerShare() external view returns (uint256 _pricePerShare) {\n        return previewPricePerShare();\n    }\n\n    /// @notice The current totalAssets, accounting for any elapsed time since the last sync\n    /// @dev This function simulates the rewards that will be distributed at the top of the block\n    /// @return _totalAssets The total assets available in the vault\n    function totalAssets() public view virtual override returns (uint256 _totalAssets) {\n        _totalAssets = _previewTotalAssets(block.timestamp);\n    }\n\n    // ---------------------------------------------\n    // WRITE FUNCTIONS\n    // ---------------------------------------------\n\n    /// @notice Update pricePerShareStored and storedTotalAssets\n    /// @return _pricePerShare Current pricePerShare, in UNDERLYING_PRECISION\n    function sync() public returns (uint256 _pricePerShare) {\n        // Calculate the current values\n        _pricePerShare = _previewPricePerShare(block.timestamp);\n\n        // Update the state variables\n        pricePerShareStored = _pricePerShare;\n        lastSync = block.timestamp;\n    }\n\n    /// @notice DEPRECATED: The ```deposit``` function allows a user to mint shares by depositing underlying\n    /// @param _assets The amount of underlying to deposit\n    /// @param _receiver The address to send the shares to\n    /// @return _shares The amount of shares minted\n    function deposit(uint256 _assets, address _receiver) public override returns (uint256 _shares) {\n        revert MintRedeemsDisabled();\n    }\n\n    /// @notice DEPRECATED: The ```mint``` function allows a user to mint a given number of shares\n    /// @param _shares The amount of shares to mint\n    /// @param _receiver The address to send the shares to\n    /// @return _assets The amount of underlying deposited\n    function mint(uint256 _shares, address _receiver) public override returns (uint256 _assets) {\n        revert MintRedeemsDisabled();\n    }\n\n    /// @notice DEPRECATED: The ```withdraw``` function allows a user to withdraw a given amount of underlying\n    /// @param _assets The amount of underlying to withdraw\n    /// @param _receiver The address to send the underlying to\n    /// @param _owner The address of the owner of the shares\n    /// @return _shares The amount of shares burned\n    function withdraw(uint256 _assets, address _receiver, address _owner) public override returns (uint256 _shares) {\n        revert MintRedeemsDisabled();\n    }\n\n    /// @notice DEPRECATED: The ```redeem``` function allows a user to redeem their shares for underlying\n    /// @param _shares The amount of shares to redeem\n    /// @param _receiver The address to send the underlying to\n    /// @param _owner The address of the owner of the shares\n    /// @return _assets The amount of underlying redeemed\n    function redeem(uint256 _shares, address _receiver, address _owner) public override returns (uint256 _assets) {\n        revert MintRedeemsDisabled();\n    }\n\n    /// @notice DEPRECATED: The ```depositWithSignature``` function allows a user to use signed approvals to deposit\n    /// @param _assets The amount of underlying to deposit\n    /// @param _receiver The address to send the shares to\n    /// @param _deadline The deadline for the signature\n    /// @param _approveMax Whether or not to approve the maximum amount\n    /// @param _v The v value of the signature\n    /// @param _r The r value of the signature\n    /// @param _s The s value of the signature\n    /// @return _shares The amount of shares minted\n    function depositWithSignature(\n        uint256 _assets,\n        address _receiver,\n        uint256 _deadline,\n        bool _approveMax,\n        uint8 _v,\n        bytes32 _r,\n        bytes32 _s\n    ) external returns (uint256 _shares) {\n        revert MintRedeemsDisabled();\n    }\n\n    /*//////////////////////////////////////////////////////////////\n    //////          ERC4626 ACCOUNTING LOGIC OVERRIDES\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice DEPRECATED: Will always return 0.\n    function previewDeposit(uint256 assets) public view override returns (uint256) {\n        return 0;\n    }\n\n    /// @notice DEPRECATED: Will always return 0.\n    function previewMint(uint256 shares) public view override returns (uint256) {\n        return 0;\n    }\n\n    /// @notice DEPRECATED: Will always return 0.\n    function previewWithdraw(uint256 assets) public view override returns (uint256) {\n        return 0;\n    }\n\n    /// @notice DEPRECATED: Will always return 0.\n    function previewRedeem(uint256 shares) public view override returns (uint256) {\n        return 0;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n    //////    ERC4626 DEPOSIT/WITHDRAWAL LIMIT LOGIC OVERRIDES\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice DEPRECATED: Will always return 0.\n    function maxDeposit(address) public view override returns (uint256) {\n        return 0;\n    }\n\n    /// @notice DEPRECATED: Will always return 0.\n    function maxMint(address) public view override returns (uint256) {\n        return 0;\n    }\n\n    /// @notice DEPRECATED: Will always return 0.\n    function maxWithdraw(address owner) public view override returns (uint256) {\n        return 0;\n    }\n\n    /// @notice DEPRECATED: Will always return 0.\n    function maxRedeem(address owner) public view override returns (uint256) {\n        return 0;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n    //////    Backward compatible yield view functions to match old interface\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice DEPRECATED: use pricePerShareIncPerSecond instead\n    function maxDistributionPerSecondPerAsset() external view returns (uint256) {\n        // Return the maximum distribution per second per asset\n        return pricePerShareIncPerSecond;\n    }\n\n    /// @notice DEPRECATED: use pricePerShareIncPerSecond instead\n    function rewardsCycleData() external view returns (RewardsCycleData memory) {\n        // Return the rewards cycle data as the max possible rate, rate is curbed by maxDistributionPerSecondPerAsset\n        return\n            RewardsCycleData({\n                cycleEnd: uint40(block.timestamp + REWARDS_CYCLE_LENGTH),\n                lastSync: uint40(block.timestamp),\n                rewardCycleAmount: uint216(type(uint216).max / 1e18) // max value\n            });\n    }\n\n    function lastRewardsDistribution() external view returns (uint256) {\n        return block.timestamp;\n    }\n\n    //==============================================================================\n    // Errors\n    //==============================================================================\n\n    /// @notice If the asset is not 18 decimals\n    error UnderlyingAssetMustBe18Decimals();\n\n    /// @notice When the provided APY is invalid\n    error InvalidAPY();\n\n    /// @notice When a user attempts to Mint/Redeem\n    error MintRedeemsDisabled();\n\n    //==============================================================================\n    // Events\n    //==============================================================================\n}\n"},{"file_path":"node_modules/@prb/math/src/Common.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n                                CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The maximum value a uint64 number can have.\nuint64 constant MAX_UINT64 = type(uint64).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n    unchecked {\n        // Start from 0.5 in the 192.64-bit fixed-point format.\n        result = 0x800000000000000000000000000000000000000000000000;\n\n        // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n        //\n        // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n        // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n        // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n        // we know that `x & 0xFF` is also 1.\n        if (x & 0xFF00000000000000 > 0) {\n            if (x & 0x8000000000000000 > 0) {\n                result = (result * 0x16A09E667F3BCC909) >> 64;\n            }\n            if (x & 0x4000000000000000 > 0) {\n                result = (result * 0x1306FE0A31B7152DF) >> 64;\n            }\n            if (x & 0x2000000000000000 > 0) {\n                result = (result * 0x1172B83C7D517ADCE) >> 64;\n            }\n            if (x & 0x1000000000000000 > 0) {\n                result = (result * 0x10B5586CF9890F62A) >> 64;\n            }\n            if (x & 0x800000000000000 > 0) {\n                result = (result * 0x1059B0D31585743AE) >> 64;\n            }\n            if (x & 0x400000000000000 > 0) {\n                result = (result * 0x102C9A3E778060EE7) >> 64;\n            }\n            if (x & 0x200000000000000 > 0) {\n                result = (result * 0x10163DA9FB33356D8) >> 64;\n            }\n            if (x & 0x100000000000000 > 0) {\n                result = (result * 0x100B1AFA5ABCBED61) >> 64;\n            }\n        }\n\n        if (x & 0xFF000000000000 > 0) {\n            if (x & 0x80000000000000 > 0) {\n                result = (result * 0x10058C86DA1C09EA2) >> 64;\n            }\n            if (x & 0x40000000000000 > 0) {\n                result = (result * 0x1002C605E2E8CEC50) >> 64;\n            }\n            if (x & 0x20000000000000 > 0) {\n                result = (result * 0x100162F3904051FA1) >> 64;\n            }\n            if (x & 0x10000000000000 > 0) {\n                result = (result * 0x1000B175EFFDC76BA) >> 64;\n            }\n            if (x & 0x8000000000000 > 0) {\n                result = (result * 0x100058BA01FB9F96D) >> 64;\n            }\n            if (x & 0x4000000000000 > 0) {\n                result = (result * 0x10002C5CC37DA9492) >> 64;\n            }\n            if (x & 0x2000000000000 > 0) {\n                result = (result * 0x1000162E525EE0547) >> 64;\n            }\n            if (x & 0x1000000000000 > 0) {\n                result = (result * 0x10000B17255775C04) >> 64;\n            }\n        }\n\n        if (x & 0xFF0000000000 > 0) {\n            if (x & 0x800000000000 > 0) {\n                result = (result * 0x1000058B91B5BC9AE) >> 64;\n            }\n            if (x & 0x400000000000 > 0) {\n                result = (result * 0x100002C5C89D5EC6D) >> 64;\n            }\n            if (x & 0x200000000000 > 0) {\n                result = (result * 0x10000162E43F4F831) >> 64;\n            }\n            if (x & 0x100000000000 > 0) {\n                result = (result * 0x100000B1721BCFC9A) >> 64;\n            }\n            if (x & 0x80000000000 > 0) {\n                result = (result * 0x10000058B90CF1E6E) >> 64;\n            }\n            if (x & 0x40000000000 > 0) {\n                result = (result * 0x1000002C5C863B73F) >> 64;\n            }\n            if (x & 0x20000000000 > 0) {\n                result = (result * 0x100000162E430E5A2) >> 64;\n            }\n            if (x & 0x10000000000 > 0) {\n                result = (result * 0x1000000B172183551) >> 64;\n            }\n        }\n\n        if (x & 0xFF00000000 > 0) {\n            if (x & 0x8000000000 > 0) {\n                result = (result * 0x100000058B90C0B49) >> 64;\n            }\n            if (x & 0x4000000000 > 0) {\n                result = (result * 0x10000002C5C8601CC) >> 64;\n            }\n            if (x & 0x2000000000 > 0) {\n                result = (result * 0x1000000162E42FFF0) >> 64;\n            }\n            if (x & 0x1000000000 > 0) {\n                result = (result * 0x10000000B17217FBB) >> 64;\n            }\n            if (x & 0x800000000 > 0) {\n                result = (result * 0x1000000058B90BFCE) >> 64;\n            }\n            if (x & 0x400000000 > 0) {\n                result = (result * 0x100000002C5C85FE3) >> 64;\n            }\n            if (x & 0x200000000 > 0) {\n                result = (result * 0x10000000162E42FF1) >> 64;\n            }\n            if (x & 0x100000000 > 0) {\n                result = (result * 0x100000000B17217F8) >> 64;\n            }\n        }\n\n        if (x & 0xFF000000 > 0) {\n            if (x & 0x80000000 > 0) {\n                result = (result * 0x10000000058B90BFC) >> 64;\n            }\n            if (x & 0x40000000 > 0) {\n                result = (result * 0x1000000002C5C85FE) >> 64;\n            }\n            if (x & 0x20000000 > 0) {\n                result = (result * 0x100000000162E42FF) >> 64;\n            }\n            if (x & 0x10000000 > 0) {\n                result = (result * 0x1000000000B17217F) >> 64;\n            }\n            if (x & 0x8000000 > 0) {\n                result = (result * 0x100000000058B90C0) >> 64;\n            }\n            if (x & 0x4000000 > 0) {\n                result = (result * 0x10000000002C5C860) >> 64;\n            }\n            if (x & 0x2000000 > 0) {\n                result = (result * 0x1000000000162E430) >> 64;\n            }\n            if (x & 0x1000000 > 0) {\n                result = (result * 0x10000000000B17218) >> 64;\n            }\n        }\n\n        if (x & 0xFF0000 > 0) {\n            if (x & 0x800000 > 0) {\n                result = (result * 0x1000000000058B90C) >> 64;\n            }\n            if (x & 0x400000 > 0) {\n                result = (result * 0x100000000002C5C86) >> 64;\n            }\n            if (x & 0x200000 > 0) {\n                result = (result * 0x10000000000162E43) >> 64;\n            }\n            if (x & 0x100000 > 0) {\n                result = (result * 0x100000000000B1721) >> 64;\n            }\n            if (x & 0x80000 > 0) {\n                result = (result * 0x10000000000058B91) >> 64;\n            }\n            if (x & 0x40000 > 0) {\n                result = (result * 0x1000000000002C5C8) >> 64;\n            }\n            if (x & 0x20000 > 0) {\n                result = (result * 0x100000000000162E4) >> 64;\n            }\n            if (x & 0x10000 > 0) {\n                result = (result * 0x1000000000000B172) >> 64;\n            }\n        }\n\n        if (x & 0xFF00 > 0) {\n            if (x & 0x8000 > 0) {\n                result = (result * 0x100000000000058B9) >> 64;\n            }\n            if (x & 0x4000 > 0) {\n                result = (result * 0x10000000000002C5D) >> 64;\n            }\n            if (x & 0x2000 > 0) {\n                result = (result * 0x1000000000000162E) >> 64;\n            }\n            if (x & 0x1000 > 0) {\n                result = (result * 0x10000000000000B17) >> 64;\n            }\n            if (x & 0x800 > 0) {\n                result = (result * 0x1000000000000058C) >> 64;\n            }\n            if (x & 0x400 > 0) {\n                result = (result * 0x100000000000002C6) >> 64;\n            }\n            if (x & 0x200 > 0) {\n                result = (result * 0x10000000000000163) >> 64;\n            }\n            if (x & 0x100 > 0) {\n                result = (result * 0x100000000000000B1) >> 64;\n            }\n        }\n\n        if (x & 0xFF > 0) {\n            if (x & 0x80 > 0) {\n                result = (result * 0x10000000000000059) >> 64;\n            }\n            if (x & 0x40 > 0) {\n                result = (result * 0x1000000000000002C) >> 64;\n            }\n            if (x & 0x20 > 0) {\n                result = (result * 0x10000000000000016) >> 64;\n            }\n            if (x & 0x10 > 0) {\n                result = (result * 0x1000000000000000B) >> 64;\n            }\n            if (x & 0x8 > 0) {\n                result = (result * 0x10000000000000006) >> 64;\n            }\n            if (x & 0x4 > 0) {\n                result = (result * 0x10000000000000003) >> 64;\n            }\n            if (x & 0x2 > 0) {\n                result = (result * 0x10000000000000001) >> 64;\n            }\n            if (x & 0x1 > 0) {\n                result = (result * 0x10000000000000001) >> 64;\n            }\n        }\n\n        // In the code snippet below, two operations are executed simultaneously:\n        //\n        // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n        // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n        // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n        //\n        // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n        // integer part, $2^n$.\n        result *= UNIT;\n        result >>= (191 - (x >> 64));\n    }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n///     x >>= 128;\n///     result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n    // 2^128\n    assembly (\"memory-safe\") {\n        let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^64\n    assembly (\"memory-safe\") {\n        let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^32\n    assembly (\"memory-safe\") {\n        let factor := shl(5, gt(x, 0xFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^16\n    assembly (\"memory-safe\") {\n        let factor := shl(4, gt(x, 0xFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^8\n    assembly (\"memory-safe\") {\n        let factor := shl(3, gt(x, 0xFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^4\n    assembly (\"memory-safe\") {\n        let factor := shl(2, gt(x, 0xF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^2\n    assembly (\"memory-safe\") {\n        let factor := shl(1, gt(x, 0x3))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^1\n    // No need to shift x any more.\n    assembly (\"memory-safe\") {\n        let factor := gt(x, 0x1)\n        result := or(result, factor)\n    }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n    // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n    // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n    // variables such that product = prod1 * 2^256 + prod0.\n    uint256 prod0; // Least significant 256 bits of the product\n    uint256 prod1; // Most significant 256 bits of the product\n    assembly (\"memory-safe\") {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n    }\n\n    // Handle non-overflow cases, 256 by 256 division.\n    if (prod1 == 0) {\n        unchecked {\n            return prod0 / denominator;\n        }\n    }\n\n    // Make sure the result is less than 2^256. Also prevents denominator == 0.\n    if (prod1 >= denominator) {\n        revert PRBMath_MulDiv_Overflow(x, y, denominator);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    // 512 by 256 division\n    ////////////////////////////////////////////////////////////////////////////\n\n    // Make division exact by subtracting the remainder from [prod1 prod0].\n    uint256 remainder;\n    assembly (\"memory-safe\") {\n        // Compute remainder using the mulmod Yul instruction.\n        remainder := mulmod(x, y, denominator)\n\n        // Subtract 256 bit number from 512-bit number.\n        prod1 := sub(prod1, gt(remainder, prod0))\n        prod0 := sub(prod0, remainder)\n    }\n\n    unchecked {\n        // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n        // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n        // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n        uint256 lpotdod = denominator & (~denominator + 1);\n        uint256 flippedLpotdod;\n\n        assembly (\"memory-safe\") {\n            // Factor powers of two out of denominator.\n            denominator := div(denominator, lpotdod)\n\n            // Divide [prod1 prod0] by lpotdod.\n            prod0 := div(prod0, lpotdod)\n\n            // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n            // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n            // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n            flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n        }\n\n        // Shift in bits from prod1 into prod0.\n        prod0 |= prod1 * flippedLpotdod;\n\n        // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n        // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n        // four bits. That is, denominator * inv = 1 mod 2^4.\n        uint256 inverse = (3 * denominator) ^ 2;\n\n        // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n        // in modular arithmetic, doubling the correct bits in each step.\n        inverse *= 2 - denominator * inverse; // inverse mod 2^8\n        inverse *= 2 - denominator * inverse; // inverse mod 2^16\n        inverse *= 2 - denominator * inverse; // inverse mod 2^32\n        inverse *= 2 - denominator * inverse; // inverse mod 2^64\n        inverse *= 2 - denominator * inverse; // inverse mod 2^128\n        inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n        // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n        // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n        // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n        // is no longer required.\n        result = prod0 * inverse;\n    }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n///     x * y = MAX\\_UINT256 * UNIT \\\\\n///     (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n    uint256 prod0;\n    uint256 prod1;\n    assembly (\"memory-safe\") {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n    }\n\n    if (prod1 == 0) {\n        unchecked {\n            return prod0 / UNIT;\n        }\n    }\n\n    if (prod1 >= UNIT) {\n        revert PRBMath_MulDiv18_Overflow(x, y);\n    }\n\n    uint256 remainder;\n    assembly (\"memory-safe\") {\n        remainder := mulmod(x, y, UNIT)\n        result :=\n            mul(\n                or(\n                    div(sub(prod0, remainder), UNIT_LPOTD),\n                    mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n                ),\n                UNIT_INVERSE\n            )\n    }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n    if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n        revert PRBMath_MulDivSigned_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x, y and the denominator.\n    uint256 xAbs;\n    uint256 yAbs;\n    uint256 dAbs;\n    unchecked {\n        xAbs = x < 0 ? uint256(-x) : uint256(x);\n        yAbs = y < 0 ? uint256(-y) : uint256(y);\n        dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n    }\n\n    // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n    uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n    if (resultAbs > uint256(type(int256).max)) {\n        revert PRBMath_MulDivSigned_Overflow(x, y);\n    }\n\n    // Get the signs of x, y and the denominator.\n    uint256 sx;\n    uint256 sy;\n    uint256 sd;\n    assembly (\"memory-safe\") {\n        // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n        sx := sgt(x, sub(0, 1))\n        sy := sgt(y, sub(0, 1))\n        sd := sgt(denominator, sub(0, 1))\n    }\n\n    // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n    // If there are, the result should be negative. Otherwise, it should be positive.\n    unchecked {\n        result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n    }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n    if (x == 0) {\n        return 0;\n    }\n\n    // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n    //\n    // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n    //\n    // $$\n    // msb(x) <= x <= 2*msb(x)$\n    // $$\n    //\n    // We write $msb(x)$ as $2^k$, and we get:\n    //\n    // $$\n    // k = log_2(x)\n    // $$\n    //\n    // Thus, we can write the initial inequality as:\n    //\n    // $$\n    // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n    // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n    // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n    // $$\n    //\n    // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n    uint256 xAux = uint256(x);\n    result = 1;\n    if (xAux >= 2 ** 128) {\n        xAux >>= 128;\n        result <<= 64;\n    }\n    if (xAux >= 2 ** 64) {\n        xAux >>= 64;\n        result <<= 32;\n    }\n    if (xAux >= 2 ** 32) {\n        xAux >>= 32;\n        result <<= 16;\n    }\n    if (xAux >= 2 ** 16) {\n        xAux >>= 16;\n        result <<= 8;\n    }\n    if (xAux >= 2 ** 8) {\n        xAux >>= 8;\n        result <<= 4;\n    }\n    if (xAux >= 2 ** 4) {\n        xAux >>= 4;\n        result <<= 2;\n    }\n    if (xAux >= 2 ** 2) {\n        result <<= 1;\n    }\n\n    // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n    // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n    // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n    // precision into the expected uint128 result.\n    unchecked {\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n\n        // If x is not a perfect square, round the result toward zero.\n        uint256 roundedResult = x / result;\n        if (result >= roundedResult) {\n            result = roundedResult;\n        }\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/ud60x18/Math.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n    uEXP_MAX_INPUT,\n    uEXP2_MAX_INPUT,\n    uHALF_UNIT,\n    uLOG2_10,\n    uLOG2_E,\n    uMAX_UD60x18,\n    uMAX_WHOLE_UD60x18,\n    UNIT,\n    uUNIT,\n    uUNIT_SQUARED,\n    ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n                            MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    uint256 yUint = y.unwrap();\n    unchecked {\n        result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n    }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x ≤ MAX_WHOLE_UD60x18\n///\n/// @param x The UD60x18 number to ceil.\n/// @return result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    if (xUint > uMAX_WHOLE_UD60x18) {\n        revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n    }\n\n    assembly (\"memory-safe\") {\n        // Equivalent to `x % UNIT`.\n        let remainder := mod(x, uUNIT)\n\n        // Equivalent to `UNIT - remainder`.\n        let delta := sub(uUNIT, remainder)\n\n        // Equivalent to `x + remainder > 0 ? delta : 0`.\n        result := add(x, mul(delta, gt(remainder, 0)))\n    }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @return result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x ≤ 133_084258667509499440\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    // This check prevents values greater than 192e18 from being passed to {exp2}.\n    if (xUint > uEXP_MAX_INPUT) {\n        revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n    }\n\n    unchecked {\n        // Inline the fixed-point multiplication to save gas.\n        uint256 doubleUnitProduct = xUint * uLOG2_E;\n        result = exp2(wrap(doubleUnitProduct / uUNIT));\n    }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x < 192e18\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n    if (xUint > uEXP2_MAX_INPUT) {\n        revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n    }\n\n    // Convert x to the 192.64-bit fixed-point format.\n    uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n    // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n    result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @return result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n    assembly (\"memory-safe\") {\n        // Equivalent to `x % UNIT`.\n        let remainder := mod(x, uUNIT)\n\n        // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n        result := sub(x, mul(remainder, gt(remainder, 0)))\n    }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @return result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n    assembly (\"memory-safe\") {\n        result := mod(x, uUNIT)\n    }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    uint256 yUint = y.unwrap();\n    if (xUint == 0 || yUint == 0) {\n        return ZERO;\n    }\n\n    unchecked {\n        // Checking for overflow this way is faster than letting Solidity do it.\n        uint256 xyUint = xUint * yUint;\n        if (xyUint / xUint != yUint) {\n            revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n        }\n\n        // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n        // during multiplication. See the comments in {Common.sqrt}.\n        result = wrap(Common.sqrt(xyUint));\n    }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n    unchecked {\n        result = wrap(uUNIT_SQUARED / x.unwrap());\n    }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n    unchecked {\n        // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n        // {log2} can return is ~196_205294292027477728.\n        result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n    }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    if (xUint < uUNIT) {\n        revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n    }\n\n    // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n    // prettier-ignore\n    assembly (\"memory-safe\") {\n        switch x\n        case 1 { result := mul(uUNIT, sub(0, 18)) }\n        case 10 { result := mul(uUNIT, sub(1, 18)) }\n        case 100 { result := mul(uUNIT, sub(2, 18)) }\n        case 1000 { result := mul(uUNIT, sub(3, 18)) }\n        case 10000 { result := mul(uUNIT, sub(4, 18)) }\n        case 100000 { result := mul(uUNIT, sub(5, 18)) }\n        case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n        case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n        case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n        case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n        case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n        case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n        case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n        case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n        case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n        case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n        case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n        case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n        case 1000000000000000000 { result := 0 }\n        case 10000000000000000000 { result := uUNIT }\n        case 100000000000000000000 { result := mul(uUNIT, 2) }\n        case 1000000000000000000000 { result := mul(uUNIT, 3) }\n        case 10000000000000000000000 { result := mul(uUNIT, 4) }\n        case 100000000000000000000000 { result := mul(uUNIT, 5) }\n        case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n        case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n        case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n        case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n        case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n        case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n        case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n        case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n        case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n        case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n        case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n        case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n        case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n        case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n        case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n        case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n        case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n        case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n        case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n        case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n        case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n        case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n        case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n        case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n        case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n        case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n        case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n        case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n        case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n        case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n        case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n        case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n        case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n        case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n        case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n        case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n        case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n        case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n        case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n        case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n        case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n        case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n        default { result := uMAX_UD60x18 }\n    }\n\n    if (result.unwrap() == uMAX_UD60x18) {\n        unchecked {\n            // Inline the fixed-point division to save gas.\n            result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n        }\n    }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x ≥ UNIT\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    if (xUint < uUNIT) {\n        revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n    }\n\n    unchecked {\n        // Calculate the integer part of the logarithm.\n        uint256 n = Common.msb(xUint / uUNIT);\n\n        // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n        // n is at most 255 and UNIT is 1e18.\n        uint256 resultUint = n * uUNIT;\n\n        // Calculate $y = x * 2^{-n}$.\n        uint256 y = xUint >> n;\n\n        // If y is the unit number, the fractional part is zero.\n        if (y == uUNIT) {\n            return wrap(resultUint);\n        }\n\n        // Calculate the fractional part via the iterative approximation.\n        // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n        uint256 DOUBLE_UNIT = 2e18;\n        for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n            y = (y * y) / uUNIT;\n\n            // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n            if (y >= DOUBLE_UNIT) {\n                // Add the 2^{-m} factor to the logarithm.\n                resultUint += delta;\n\n                // Halve y, which corresponds to z/2 in the Wikipedia article.\n                y >>= 1;\n            }\n        }\n        result = wrap(resultUint);\n    }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    uint256 yUint = y.unwrap();\n\n    // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n    if (xUint == 0) {\n        return yUint == 0 ? UNIT : ZERO;\n    }\n    // If x is `UNIT`, the result is always `UNIT`.\n    else if (xUint == uUNIT) {\n        return UNIT;\n    }\n\n    // If y is zero, the result is always `UNIT`.\n    if (yUint == 0) {\n        return UNIT;\n    }\n    // If y is `UNIT`, the result is always x.\n    else if (yUint == uUNIT) {\n        return x;\n    }\n\n    // If x is > UNIT, use the standard formula.\n    if (xUint > uUNIT) {\n        result = exp2(mul(log2(x), y));\n    }\n    // Conversely, if x < UNIT, use the equivalent formula.\n    else {\n        UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n        UD60x18 w = exp2(mul(log2(i), y));\n        result = wrap(uUNIT_SQUARED / w.unwrap());\n    }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n    // Calculate the first iteration of the loop in advance.\n    uint256 xUint = x.unwrap();\n    uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n    // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n    for (y >>= 1; y > 0; y >>= 1) {\n        xUint = Common.mulDiv18(xUint, xUint);\n\n        // Equivalent to `y % 2 == 1`.\n        if (y & 1 > 0) {\n            resultUint = Common.mulDiv18(resultUint, xUint);\n        }\n    }\n    result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x ≤ MAX_UD60x18 / UNIT\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    unchecked {\n        if (xUint > uMAX_UD60x18 / uUNIT) {\n            revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n        }\n        // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n        // In this case, the two numbers are both the square root.\n        result = wrap(Common.sqrt(xUint * uUNIT));\n    }\n}\n"},{"file_path":"src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD2.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.21;\n\n// ====================================================================\n// |     ______                   _______                             |\n// |    / _____________ __  __   / ____(_____  ____ _____  ________   |\n// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \\/ __ `/ __ \\/ ___/ _ \\  |\n// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |\n// | /_/   /_/   \\__,_/_/|_|  /_/   /_/_/ /_/\\__,_/_/ /_/\\___/\\___/   |\n// |                                                                  |\n// ====================================================================\n// ========================== StakedFrxUSD2 ===========================\n// ====================================================================\n// Frax Finance: https://github.com/FraxFinance\n// Tested for 18-decimal underlying assets only\n\nimport { Timelock2Step } from \"frax-std/access-control/v2/Timelock2Step.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts-5.3.0/token/ERC20/ERC20.sol\";\nimport { LinearRewardsErc4626_2, ERC20 } from \"src/contracts/ethereum/sfrxUSD/inherited/LinearRewardsErc4626_2.sol\";\n\n/// @title Staked frxUSD\n/// @notice A ERC4626-like Vault implementation with linear rewards, rewards can be capped\ncontract SfrxUSD2 is LinearRewardsErc4626_2, Timelock2Step {\n    /// @notice Used for initialization\n    bool public _initialized;\n\n    /// @notice Array of minters\n    address[] public minters_array;\n\n    /// @notice Mapping of the minters\n    /// @dev Mapping is used for faster verification\n    mapping(address => bool) public minters;\n\n    function version() public pure virtual returns (string memory) {\n        return \"2.0.1\";\n    }\n\n    /// @param _underlying The erc20 asset deposited\n    /// @param _name The name of the vault\n    /// @param _symbol The symbol of the vault\n    /// @param _timelockAddress The address of the timelock/owner contract\n    constructor(\n        IERC20 _underlying,\n        string memory _name,\n        string memory _symbol,\n        address _timelockAddress\n    ) LinearRewardsErc4626_2(ERC20(address(_underlying)), _name, _symbol) Timelock2Step(_timelockAddress) {\n        _initialized = true;\n    }\n\n    /* ========== MODIFIERS ========== */\n\n    /// @notice A modifier that only allows a minters to call\n    modifier onlyMinters() {\n        if (!minters[msg.sender]) revert OnlyMinters();\n        _;\n    }\n\n    /* ========== UNRESTRICTED FUNCTIONS========== */\n\n    /// @notice Burn tokens. You do NOT receive any underlying assets when doing so\n    /// @param _amount Amount of tokens to burn\n    function burn(uint256 _amount) public {\n        // Do the burn\n        super._burn(msg.sender, _amount);\n\n        emit Burn(msg.sender, _amount);\n    }\n\n    /* ========== RESTRICTED FUNCTIONS [MINTERS] ========== */\n\n    /// @notice Used by minters to burn tokens\n    /// @param b_address Address of the account to burn from\n    /// @param b_amount Amount of tokens to burn\n    function minter_burn_from(address b_address, uint256 b_amount) public onlyMinters {\n        super._burn(b_address, b_amount);\n        emit TokenMinterBurned(b_address, msg.sender, b_amount);\n    }\n\n    /// @notice Used by minters to mint new tokens\n    /// @param m_address Address of the account to mint to\n    /// @param m_amount Amount of tokens to mint\n    function minter_mint(address m_address, uint256 m_amount) public onlyMinters {\n        super._mint(m_address, m_amount);\n        emit TokenMinterMinted(msg.sender, m_address, m_amount);\n    }\n\n    /* ========== RESTRICTED FUNCTIONS [OWNER] ========== */\n    /// @notice Adds a minter\n    /// @param minter_address Address of minter to add\n    function addMinter(address minter_address) public {\n        _requireSenderIsTimelock();\n        require(minter_address != address(0), \"Zero address detected\");\n\n        require(minters[minter_address] == false, \"Address already exists\");\n        minters[minter_address] = true;\n        minters_array.push(minter_address);\n\n        emit MinterAdded(minter_address);\n    }\n\n    /// @notice Removes a non-bridge minter\n    /// @param minter_address Address of minter to remove\n    function removeMinter(address minter_address) public {\n        _requireSenderIsTimelock();\n        require(minter_address != address(0), \"Zero address detected\");\n        require(minters[minter_address] == true, \"Address nonexistant\");\n\n        // Delete from the mapping\n        delete minters[minter_address];\n\n        // 'Delete' from the array by setting the address to 0x0\n        for (uint256 i = 0; i < minters_array.length; i++) {\n            if (minters_array[i] == minter_address) {\n                minters_array[i] = address(0); // This will leave a null in the array and keep the indices the same\n                break;\n            }\n        }\n\n        emit MinterRemoved(minter_address);\n    }\n\n    /// @notice Set pricePerShareStored, pricePerShareIncPerSecond, and lastSync in one call\n    /// @param _newPricePerShareStored New stored price per share, in E18 asset tokens\n    /// @param _newPricePerShareIncPerSecond New stored price per share increase per second, in E18 asset tokens\n    /// @param _newLastSync New lastSync\n    /// @dev p(t) = p0*e^(r(t-t0))\n    function setAllPricingParams(\n        uint256 _newPricePerShareStored,\n        uint256 _newPricePerShareIncPerSecond,\n        uint256 _newLastSync\n    ) external {\n        _requireSenderIsTimelock();\n\n        // Make sure lastSync is not in the future\n        if (_newLastSync > block.timestamp) revert MustNotBeInTheFuture();\n\n        // Set the 3 parameters\n        pricePerShareStored = _newPricePerShareStored;\n        pricePerShareIncPerSecond = _newPricePerShareIncPerSecond;\n        lastSync = _newLastSync;\n\n        emit SetPricePerShareStored(_newPricePerShareStored);\n        emit SetPricePerShareIncPerSecond(_newPricePerShareIncPerSecond);\n        emit SetLastSync(_newLastSync);\n    }\n\n    /// @notice Set pricePerShare increase rate, per second (pricePerShareIncPerSecond). Also sets lastSync to now and pricePerShareStored to the current pricePerShare\n    /// @param _newPricePerShareIncPerSecond New stored price per share increase per second, in E18 asset tokens\n    function setPricePerShareIncPerSecond(uint256 _newPricePerShareIncPerSecond) external {\n        _requireSenderIsTimelock();\n\n        // Sync first\n        sync();\n\n        // Set pricePerShareIncPerSecond\n        pricePerShareIncPerSecond = _newPricePerShareIncPerSecond;\n\n        emit SetPricePerShareIncPerSecond(_newPricePerShareIncPerSecond);\n    }\n\n    /// @notice Set pricePerShareStored\n    /// @param _newPricePerShareStored New stored price per share, in E18 asset tokens\n    function setPricePerShareStored(uint256 _newPricePerShareStored) external {\n        _requireSenderIsTimelock();\n\n        // Set lastSync to now\n        lastSync = block.timestamp;\n\n        // Set pricePerShareStored\n        pricePerShareStored = _newPricePerShareStored;\n\n        emit SetPricePerShareStored(_newPricePerShareStored);\n    }\n\n    //==============================================================================\n    // Errors\n    //==============================================================================\n\n    /// @notice When lastSync is trying to be set to a future date\n    error MustNotBeInTheFuture();\n\n    /// @notice When a non-minter tries to call a restricted function\n    error OnlyMinters();\n\n    //==============================================================================\n    // Events\n    //==============================================================================\n\n    /// @notice Emitted when a burn happens\n    /// @param from The address whose tokens were burned\n    /// @param amount Amount of tokens burned\n    event Burn(address indexed from, uint256 amount);\n\n    /// @notice Emitted when a mint happens\n    /// @param to Recipient of the newly-minted tokens\n    /// @param amount Amount of tokens minted\n    event Mint(address indexed to, uint256 amount);\n\n    /// @notice Emitted when a non-bridge minter is added\n    /// @param minter_address Address of the new minter\n    event MinterAdded(address minter_address);\n\n    /// @notice Emitted when a non-bridge minter is removed\n    /// @param minter_address Address of the removed minter\n    event MinterRemoved(address minter_address);\n\n    /// @notice When setLastSync is called\n    /// @param newLastSync New lastSync\n    event SetLastSync(uint256 newLastSync);\n\n    /// @notice When setPricePerShareIncPerSecond is called\n    /// @param newPricePerShareIncPerSecond New stored price per share increase per second, in E18 asset tokens\n    event SetPricePerShareIncPerSecond(uint256 newPricePerShareIncPerSecond);\n\n    /// @notice When setPricePerShareStored is called\n    /// @param newPricePerShareStored New stored price per share, in E18 asset tokens\n    event SetPricePerShareStored(uint256 newPricePerShareStored);\n\n    /// @notice Emitted when a non-bridge minter burns tokens\n    /// @param from The account whose tokens are burned\n    /// @param to The minter doing the burning\n    /// @param amount Amount of tokens burned\n    event TokenMinterBurned(address indexed from, address indexed to, uint256 amount);\n\n    /// @notice Emitted when a non-bridge minter mints tokens\n    /// @param from The minter doing the minting\n    /// @param to The account that gets the newly minted tokens\n    /// @param amount Amount of tokens minted\n    event TokenMinterMinted(address indexed from, address indexed to, uint256 amount);\n}\n"},{"file_path":"node_modules/@prb/math/src/ud21x18/Casting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD21x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD21x18 number into SD59x18.\n/// @dev There is no overflow check because UD21x18 ⊆ SD59x18.\nfunction intoSD59x18(UD21x18 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(int256(uint256(UD21x18.unwrap(x))));\n}\n\n/// @notice Casts a UD21x18 number into UD60x18.\n/// @dev There is no overflow check because UD21x18 ⊆ UD60x18.\nfunction intoUD60x18(UD21x18 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(UD21x18.unwrap(x));\n}\n\n/// @notice Casts a UD21x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint128(UD21x18 x) pure returns (uint128 result) {\n    result = UD21x18.unwrap(x);\n}\n\n/// @notice Casts a UD21x18 number into uint256.\n/// @dev There is no overflow check because UD21x18 ⊆ uint256.\nfunction intoUint256(UD21x18 x) pure returns (uint256 result) {\n    result = uint256(UD21x18.unwrap(x));\n}\n\n/// @notice Casts a UD21x18 number into uint40.\n/// @dev Requirements:\n/// - x ≤ MAX_UINT40\nfunction intoUint40(UD21x18 x) pure returns (uint40 result) {\n    uint128 xUint = UD21x18.unwrap(x);\n    if (xUint > uint128(Common.MAX_UINT40)) {\n        revert Errors.PRBMath_UD21x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud21x18(uint128 x) pure returns (UD21x18 result) {\n    result = UD21x18.wrap(x);\n}\n\n/// @notice Unwrap a UD21x18 number into uint128.\nfunction unwrap(UD21x18 x) pure returns (uint128 result) {\n    result = UD21x18.unwrap(x);\n}\n\n/// @notice Wraps a uint128 number into UD21x18.\nfunction wrap(uint128 x) pure returns (UD21x18 result) {\n    result = UD21x18.wrap(x);\n}\n"},{"file_path":"node_modules/@prb/math/src/ud21x18/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD21x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD21x18 number that doesn't fit in uint40.\nerror PRBMath_UD21x18_IntoUint40_Overflow(UD21x18 x);\n"},{"file_path":"node_modules/@prb/math/src/ud2x18/Constants.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n"},{"file_path":"node_modules/solmate/src/utils/FixedPointMathLib.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\nlibrary FixedPointMathLib {\n    /*//////////////////////////////////////////////////////////////\n                    SIMPLIFIED FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal constant MAX_UINT256 = 2**256 - 1;\n\n    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n    }\n\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n    }\n\n    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n    }\n\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                    LOW LEVEL FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function mulDivDown(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // Divide x * y by the denominator.\n            z := div(mul(x, y), denominator)\n        }\n    }\n\n    function mulDivUp(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // If x * y modulo the denominator is strictly greater than 0,\n            // 1 is added to round up the division of x * y by the denominator.\n            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))\n        }\n    }\n\n    function rpow(\n        uint256 x,\n        uint256 n,\n        uint256 scalar\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            switch x\n            case 0 {\n                switch n\n                case 0 {\n                    // 0 ** 0 = 1\n                    z := scalar\n                }\n                default {\n                    // 0 ** n = 0\n                    z := 0\n                }\n            }\n            default {\n                switch mod(n, 2)\n                case 0 {\n                    // If n is even, store scalar in z for now.\n                    z := scalar\n                }\n                default {\n                    // If n is odd, store x in z for now.\n                    z := x\n                }\n\n                // Shifting right by 1 is like dividing by 2.\n                let half := shr(1, scalar)\n\n                for {\n                    // Shift n right by 1 before looping to halve it.\n                    n := shr(1, n)\n                } n {\n                    // Shift n right by 1 each iteration to halve it.\n                    n := shr(1, n)\n                } {\n                    // Revert immediately if x ** 2 would overflow.\n                    // Equivalent to iszero(eq(div(xx, x), x)) here.\n                    if shr(128, x) {\n                        revert(0, 0)\n                    }\n\n                    // Store x squared.\n                    let xx := mul(x, x)\n\n                    // Round to the nearest number.\n                    let xxRound := add(xx, half)\n\n                    // Revert if xx + half overflowed.\n                    if lt(xxRound, xx) {\n                        revert(0, 0)\n                    }\n\n                    // Set x to scaled xxRound.\n                    x := div(xxRound, scalar)\n\n                    // If n is even:\n                    if mod(n, 2) {\n                        // Compute z * x.\n                        let zx := mul(z, x)\n\n                        // If z * x overflowed:\n                        if iszero(eq(div(zx, x), z)) {\n                            // Revert if x is non-zero.\n                            if iszero(iszero(x)) {\n                                revert(0, 0)\n                            }\n                        }\n\n                        // Round to the nearest number.\n                        let zxRound := add(zx, half)\n\n                        // Revert if zx + half overflowed.\n                        if lt(zxRound, zx) {\n                            revert(0, 0)\n                        }\n\n                        // Return properly scaled zxRound.\n                        z := div(zxRound, scalar)\n                    }\n                }\n            }\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        GENERAL NUMBER UTILITIES\n    //////////////////////////////////////////////////////////////*/\n\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let y := x // We start y at x, which will help us make our initial estimate.\n\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // We check y >= 2^(k + 8) but shift right by k bits\n            // each branch to ensure that if x >= 256, then y >= 256.\n            if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n                y := shr(128, y)\n                z := shl(64, z)\n            }\n            if iszero(lt(y, 0x1000000000000000000)) {\n                y := shr(64, y)\n                z := shl(32, z)\n            }\n            if iszero(lt(y, 0x10000000000)) {\n                y := shr(32, y)\n                z := shl(16, z)\n            }\n            if iszero(lt(y, 0x1000000)) {\n                y := shr(16, y)\n                z := shl(8, z)\n            }\n\n            // Goal was to get z*z*y within a small factor of x. More iterations could\n            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n            // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n            // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n            // There is no overflow risk here since y < 2^136 after the first branch above.\n            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If x+1 is a perfect square, the Babylonian method cycles between\n            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Mod x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            z := mod(x, y)\n        }\n    }\n\n    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Divide x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            r := div(x, y)\n        }\n    }\n\n    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Add 1 to x * y if x % y > 0. Note this will\n            // return 0 instead of reverting if y is zero.\n            z := add(gt(mod(x, y), 0), div(x, y))\n        }\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/sd59x18/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in SD21x18.\nerror PRBMath_SD59x18_IntoSD21x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in SD21x18.\nerror PRBMath_SD59x18_IntoSD21x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in UD21x18.\nerror PRBMath_SD59x18_IntoUD21x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in UD21x18.\nerror PRBMath_SD59x18_IntoUD21x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast an SD59x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/interfaces/IERC1271.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n */\ninterface IERC1271 {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param hash      Hash of the data to be signed\n     * @param signature Signature byte array associated with `hash`\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts-5.3.0/utils/cryptography/ECDSA.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\n     * return address(0) without also returning an error description. Errors are documented using an enum (error type)\n     * and a bytes32 providing additional information about the error.\n     *\n     * If no error is returned, then the address can be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes memory signature\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly (\"memory-safe\") {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        unchecked {\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            return tryRecover(hash, v, r, s);\n        }\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS, s);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature, bytes32(0));\n        }\n\n        return (signer, RecoverError.NoError, bytes32(0));\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\n     */\n    function _throwError(RecoverError error, bytes32 errorArg) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert ECDSAInvalidSignature();\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert ECDSAInvalidSignatureLength(uint256(errorArg));\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert ECDSAInvalidSignatureS(errorArg);\n        }\n    }\n}\n"},{"file_path":"node_modules/@prb/math/src/ud2x18/Casting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because UD2x18 ⊆ SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because UD2x18 ⊆ UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because UD2x18 ⊆ uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n    result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because UD2x18 ⊆ uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n    result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x ≤ MAX_UINT40\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n    uint64 xUint = UD2x18.unwrap(x);\n    if (xUint > uint64(Common.MAX_UINT40)) {\n        revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n    result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n    result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n    result = UD2x18.wrap(x);\n}\n"},{"file_path":"node_modules/@prb/math/src/sd1x18/Casting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because SD1x18 ⊆ SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n    }\n    result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n    }\n    result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x ≥ 0\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n    }\n    result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x ≥ 0\n/// - x ≤ MAX_UINT40\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n    }\n    if (xInt > int64(uint64(Common.MAX_UINT40))) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n    }\n    result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n    result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n    result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n    result = SD1x18.wrap(x);\n}\n"},{"file_path":"node_modules/@prb/math/src/ud21x18/ValueType.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 21.18-decimal fixed-point number representation, which can have up to 21 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint128. This is useful when end users want to use uint128 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD21x18 is uint128;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD59x18,\n    Casting.intoUD60x18,\n    Casting.intoUint128,\n    Casting.intoUint256,\n    Casting.intoUint40,\n    Casting.unwrap\n} for UD21x18 global;\n"},{"file_path":"src/contracts/shared/core/modules/SignatureModule.sol","source_code":"pragma solidity ^0.8.0;\n\nimport { SignatureChecker } from \"@openzeppelin/contracts-5.3.0/utils/cryptography/SignatureChecker.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts that use EIP-712 signatures.\n * It provides functionality to initialize the EIP-712 domain separator and verify signatures.\n */\nabstract contract SignatureModule {\n    /// @notice Error thrown when a signature is invalid\n    error InvalidSignature();\n\n    /// @dev Added supportive function to check if the signature is valid\n    function _requireIsValidSignatureNow(address signer, bytes32 structHash, bytes memory signature) internal view {\n        if (\n            !SignatureChecker.isValidSignatureNow({\n                signer: signer,\n                hash: __hashTypedDataV4({ structHash: structHash }),\n                signature: signature\n            })\n        ) revert InvalidSignature();\n    }\n\n    function __hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32);\n}\n"},{"file_path":"node_modules/@prb/math/src/sd21x18/ValueType.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 21.18-decimal fixed-point number representation, which can have up to 21 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int128. This is useful when end users want to use int128 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD21x18 is int128;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD59x18,\n    Casting.intoUD60x18,\n    Casting.intoUint128,\n    Casting.intoUint256,\n    Casting.intoUint40,\n    Casting.unwrap\n} for SD21x18 global;\n"},{"file_path":"node_modules/@prb/math/src/sd21x18/Constants.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD21x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD21x18 number.\nSD21x18 constant E = SD21x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD21x18 number can have.\nint128 constant uMAX_SD21x18 = 170141183460469231731_687303715884105727;\nSD21x18 constant MAX_SD21x18 = SD21x18.wrap(uMAX_SD21x18);\n\n/// @dev The minimum value an SD21x18 number can have.\nint128 constant uMIN_SD21x18 = -170141183460469231731_687303715884105728;\nSD21x18 constant MIN_SD21x18 = SD21x18.wrap(uMIN_SD21x18);\n\n/// @dev PI as an SD21x18 number.\nSD21x18 constant PI = SD21x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD21x18.\nSD21x18 constant UNIT = SD21x18.wrap(1e18);\nint128 constant uUNIT = 1e18;\n"},{"file_path":"node_modules/@prb/math/src/sd59x18/ValueType.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoInt256,\n    Casting.intoSD1x18,\n    Casting.intoSD21x18,\n    Casting.intoUD2x18,\n    Casting.intoUD21x18,\n    Casting.intoUD60x18,\n    Casting.intoUint256,\n    Casting.intoUint128,\n    Casting.intoUint40,\n    Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                            MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Math.abs,\n    Math.avg,\n    Math.ceil,\n    Math.div,\n    Math.exp,\n    Math.exp2,\n    Math.floor,\n    Math.frac,\n    Math.gm,\n    Math.inv,\n    Math.log10,\n    Math.log2,\n    Math.ln,\n    Math.mul,\n    Math.pow,\n    Math.powu,\n    Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Helpers.add,\n    Helpers.and,\n    Helpers.eq,\n    Helpers.gt,\n    Helpers.gte,\n    Helpers.isZero,\n    Helpers.lshift,\n    Helpers.lt,\n    Helpers.lte,\n    Helpers.mod,\n    Helpers.neq,\n    Helpers.not,\n    Helpers.or,\n    Helpers.rshift,\n    Helpers.sub,\n    Helpers.uncheckedAdd,\n    Helpers.uncheckedSub,\n    Helpers.uncheckedUnary,\n    Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n    Helpers.add as +,\n    Helpers.and2 as &,\n    Math.div as /,\n    Helpers.eq as ==,\n    Helpers.gt as >,\n    Helpers.gte as >=,\n    Helpers.lt as <,\n    Helpers.lte as <=,\n    Helpers.mod as %,\n    Math.mul as *,\n    Helpers.neq as !=,\n    Helpers.not as ~,\n    Helpers.or as |,\n    Helpers.sub as -,\n    Helpers.unary as -,\n    Helpers.xor as ^\n} for SD59x18 global;\n"},{"file_path":"src/contracts/shared/core/modules/EIP3009Module.sol","source_code":"pragma solidity ^0.8.0;\n\nimport { SignatureModule } from \"./SignatureModule.sol\";\n\n/// @title Eip3009\n/// @notice Eip3009 provides internal implementations for gas-abstracted transfers under Eip3009 guidelines\n/// @author Frax Finance, inspired by Agora (thanks Drake)\nabstract contract EIP3009Module is SignatureModule {\n    /// @notice keccak256(\"TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\n    bytes32 internal constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =\n        0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;\n\n    /// @notice keccak256(\"ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\n    bytes32 internal constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH =\n        0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;\n\n    /// @notice keccak256(\"CancelAuthorization(address authorizer,bytes32 nonce)\")\n    bytes32 internal constant CANCEL_AUTHORIZATION_TYPEHASH =\n        0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;\n\n    //==============================================================================\n    // Storage\n    //==============================================================================\n\n    struct EIP3009ModuleStorage {\n        mapping(address authorizer => mapping(bytes32 nonce => bool used)) isAuthorizationUsed;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"frax.storage.EIP3009Module\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant EIP3009ModuleStorageLocation =\n        0x6607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500;\n\n    function _getEIP3009ModuleStorage() private pure returns (EIP3009ModuleStorage storage $) {\n        assembly {\n            $.slot := EIP3009ModuleStorageLocation\n        }\n    }\n\n    //==============================================================================\n    // Functions\n    //==============================================================================\n\n    /// @notice The ```transferWithAuthorization``` function executes a transfer with a signed authorization according to Eip3009\n    /// @dev EOA wallet signatures should be packed in the order of r, s, v\n    /// @dev added in v1.1.0\n    /// @param from Payer's address (Authorizer)\n    /// @param to Payee's address\n    /// @param value Amount to be transferred\n    /// @param validAfter The block.timestamp after which the authorization is valid\n    /// @param validBefore The block.timestamp before which the authorization is valid\n    /// @param nonce Unique nonce\n    /// @param v ECDSA signature parameter v\n    /// @param r ECDSA signature parameters r\n    /// @param s ECDSA signature parameters s\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external {\n        // Packs signature pieces into bytes\n        transferWithAuthorization({\n            from: from,\n            to: to,\n            value: value,\n            validAfter: validAfter,\n            validBefore: validBefore,\n            nonce: nonce,\n            signature: abi.encodePacked(r, s, v)\n        });\n    }\n\n    /// @notice The ```transferWithAuthorization``` function executes a transfer with a signed authorization\n    /// @dev EOA wallet signatures should be packed in the order of r, s, v\n    /// @param from Payer's address (Authorizer)\n    /// @param to Payee's address\n    /// @param value Amount to be transferred\n    /// @param validAfter The time after which this is valid (unix time)\n    /// @param validBefore The time before which this is valid (unix time)\n    /// @param nonce Unique nonce\n    /// @param signature Signature byte array produced by an EOA wallet or a contract wallet\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes memory signature\n    ) public {\n        // Checks: authorization validity\n        if (block.timestamp <= validAfter) revert InvalidAuthorization();\n        if (block.timestamp >= validBefore) revert ExpiredAuthorization();\n        _requireUnusedAuthorization({ authorizer: from, nonce: nonce });\n\n        // Checks: valid signature\n        _requireIsValidSignatureNow({\n            signer: from,\n            structHash: keccak256(\n                abi.encode(TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce)\n            ),\n            signature: signature\n        });\n\n        // Effects: mark authorization as used and transfer\n        _markAuthorizationAsUsed({ authorizer: from, nonce: nonce });\n        __transfer({ from: from, to: to, amount: value });\n    }\n\n    /// @notice The ```receiveWithAuthorization``` function receives a transfer with a signed authorization from the payer\n    /// @dev This has an additional check to ensure that the payee's address matches the caller of this function to prevent front-running attacks\n    /// @dev EOA wallet signatures should be packed in the order of r, s, v\n    /// @param from Payer's address (Authorizer)\n    /// @param to Payee's address\n    /// @param value Amount to be transferred\n    /// @param validAfter The block.timestamp after which the authorization is valid\n    /// @param validBefore The block.timestamp before which the authorization is valid\n    /// @param nonce Unique nonce\n    /// @param v ECDSA signature parameter v\n    /// @param r ECDSA signature parameters r\n    /// @param s ECDSA signature parameters s\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external {\n        // Packs signature pieces into bytes\n        receiveWithAuthorization({\n            from: from,\n            to: to,\n            value: value,\n            validAfter: validAfter,\n            validBefore: validBefore,\n            nonce: nonce,\n            signature: abi.encodePacked(r, s, v)\n        });\n    }\n\n    /// @notice The ```receiveWithAuthorization``` function receives a transfer with a signed authorization from the payer\n    /// @dev This has an additional check to ensure that the payee's address matches the caller of this function to prevent front-running attacks\n    /// @dev EOA wallet signatures should be packed in the order of r, s, v\n    /// @param from Payer's address (Authorizer)\n    /// @param to Payee's address\n    /// @param value Amount to be transferred\n    /// @param validAfter The block.timestamp after which the authorization is valid\n    /// @param validBefore The block.timestamp before which the authorization is valid\n    /// @param nonce Unique nonce\n    /// @param signature Signature byte array produced by an EOA wallet or a contract wallet\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes memory signature\n    ) public {\n        // Checks: authorization validity\n        if (to != msg.sender) revert InvalidPayee({ caller: msg.sender, payee: to });\n        if (block.timestamp <= validAfter) revert InvalidAuthorization();\n        if (block.timestamp >= validBefore) revert ExpiredAuthorization();\n        _requireUnusedAuthorization({ authorizer: from, nonce: nonce });\n\n        // Checks: valid signature\n        _requireIsValidSignatureNow({\n            signer: from,\n            structHash: keccak256(\n                abi.encode(RECEIVE_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce)\n            ),\n            signature: signature\n        });\n\n        // Effects: mark authorization as used and transfer\n        _markAuthorizationAsUsed({ authorizer: from, nonce: nonce });\n        __transfer({ from: from, to: to, amount: value });\n    }\n\n    /// @notice The ```cancelAuthorization``` function cancels an authorization nonce\n    /// @dev EOA wallet signatures should be packed in the order of r, s, v\n    /// @param authorizer   Authorizer's address\n    /// @param nonce        Nonce of the authorization\n    /// @param v            ECDSA signature v value\n    /// @param r            ECDSA signature r value\n    /// @param s            ECDSA signature s value\n    function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external {\n        cancelAuthorization({ authorizer: authorizer, nonce: nonce, signature: abi.encodePacked(r, s, v) });\n    }\n\n    /// @notice The ```cancelAuthorization``` function cancels an authorization nonce\n    /// @dev EOA wallet signatures should be packed in the order of r, s, v\n    /// @param authorizer    Authorizer's address\n    /// @param nonce         Nonce of the authorization\n    /// @param signature     Signature byte array produced by an EOA wallet or a contract wallet\n    function cancelAuthorization(address authorizer, bytes32 nonce, bytes memory signature) public {\n        _requireUnusedAuthorization({ authorizer: authorizer, nonce: nonce });\n        _requireIsValidSignatureNow({\n            signer: authorizer,\n            structHash: keccak256(abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer, nonce)),\n            signature: signature\n        });\n\n        _getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce] = true;\n        emit AuthorizationCanceled({ authorizer: authorizer, nonce: nonce });\n    }\n\n    //==============================================================================\n    // Internal Checks Functions\n    //==============================================================================\n\n    /// @notice The ```_requireUnusedAuthorization``` checks that an authorization nonce is unused\n    /// @param authorizer    Authorizer's address\n    /// @param nonce         Nonce of the authorization\n    function _requireUnusedAuthorization(address authorizer, bytes32 nonce) private view {\n        if (_getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce]) {\n            revert UsedOrCanceledAuthorization();\n        }\n    }\n\n    //==============================================================================\n    // Internal Effects Functions\n    //==============================================================================\n\n    /// @notice The ```_markAuthorizationAsUsed``` function marks an authorization nonce as used\n    /// @param authorizer    Authorizer's address\n    /// @param nonce         Nonce of the authorization\n    function _markAuthorizationAsUsed(address authorizer, bytes32 nonce) private {\n        _getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce] = true;\n        emit AuthorizationUsed({ authorizer: authorizer, nonce: nonce });\n    }\n\n    //==============================================================================\n    // Views\n    //==============================================================================\n\n    /**\n     * @notice Returns the state of an authorization\n     * @dev Nonces are randomly generated 32-byte data unique to the authorizer's\n     * address\n     * @param authorizer    Authorizer's address\n     * @param nonce         Nonce of the authorization\n     * @return True if the nonce is used\n     */\n    function authorizationState(address authorizer, bytes32 nonce) external view returns (bool) {\n        return _getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce];\n    }\n\n    //==============================================================================\n    // Overridden methods\n    //==============================================================================\n\n    function __transfer(address from, address to, uint256 amount) internal virtual returns (bool);\n\n    //==============================================================================\n    // Events\n    //==============================================================================\n\n    /// @notice ```AuthorizationUsed``` event is emitted when an authorization is used\n    /// @param authorizer Authorizer's address\n    /// @param nonce Nonce of the authorization\n    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);\n\n    /// @notice ```AuthorizationCanceled``` event is emitted when an authorization is canceled\n    /// @param authorizer Authorizer's address\n    /// @param nonce Nonce of the authorization\n    event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);\n\n    //==============================================================================\n    // Errors\n    //==============================================================================\n\n    /// @notice The ```InvalidPayee``` error is emitted when the payee does not match sender in receiveWithAuthorization\n    /// @param caller The caller of the function\n    /// @param payee The expected payee in the function\n    error InvalidPayee(address caller, address payee);\n\n    /// @notice The ```InvalidAuthorization``` error is emitted when the authorization is invalid because its too early\n    error InvalidAuthorization();\n\n    /// @notice The ```ExpiredAuthorization``` error is emitted when the authorization is expired\n    error ExpiredAuthorization();\n\n    /// @notice The ```UsedOrCanceledAuthorization``` error is emitted when the authorization nonce is already used or canceled\n    error UsedOrCanceledAuthorization();\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_underlying","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"pendingTimelockAddress","type":"address"},{"internalType":"address","name":"actualAddress","type":"address"}],"name":"AddressIsNotPendingTimelock","type":"error"},{"inputs":[{"internalType":"address","name":"timelockAddress","type":"address"},{"internalType":"address","name":"actualAddress","type":"address"}],"name":"AddressIsNotTimelock","type":"error"},{"inputs":[],"name":"ExpiredAuthorization","type":"error"},{"inputs":[],"name":"InvalidAPY","type":"error"},{"inputs":[],"name":"InvalidAuthorization","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"payee","type":"address"}],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"MintRedeemsDisabled","type":"error"},{"inputs":[],"name":"MustNotBeInTheFuture","type":"error"},{"inputs":[],"name":"OnlyMinters","type":"error"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"PRBMath_MulDiv18_Overflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"PRBMath_MulDiv_Overflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"PRBMath_UD60x18_Convert_Overflow","type":"error"},{"inputs":[{"internalType":"UD60x18","name":"x","type":"uint256"}],"name":"PRBMath_UD60x18_Exp2_InputTooBig","type":"error"},{"inputs":[{"internalType":"UD60x18","name":"x","type":"uint256"}],"name":"PRBMath_UD60x18_Exp_InputTooBig","type":"error"},{"inputs":[{"internalType":"UD60x18","name":"x","type":"uint256"}],"name":"PRBMath_UD60x18_Log_InputTooSmall","type":"error"},{"inputs":[],"name":"UnderlyingAssetMustBe18Decimals","type":"error"},{"inputs":[],"name":"UsedOrCanceledAuthorization","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter_address","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter_address","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newLastSync","type":"uint256"}],"name":"SetLastSync","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPricePerShareIncPerSecond","type":"uint256"}],"name":"SetPricePerShareIncPerSecond","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPricePerShareStored","type":"uint256"}],"name":"SetPricePerShareStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenMinterBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenMinterMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DEPRECATED__lastRewardsDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPRECATED__maxDistributionPerSecondPerAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPRECATED__pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPRECATED__rewardsCycleData","outputs":[{"internalType":"uint40","name":"cycleEnd","type":"uint40"},{"internalType":"uint40","name":"lastSync","type":"uint40"},{"internalType":"uint216","name":"rewardCycleAmount","type":"uint216"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPRECATED__storedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPRECATED__timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_YEAR_UD60X18","outputs":[{"internalType":"UD60x18","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS_CYCLE_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter_address","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apyE18","type":"uint256"}],"name":"calcPPSIPSForGivenAPY","outputs":[{"internalType":"uint256","name":"_newPPSIPS","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"bool","name":"_approveMax","type":"bool"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"depositWithSignature","outputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastRewardsDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastSync","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDistributionPerSecondPerAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"b_address","type":"address"},{"internalType":"uint256","name":"b_amount","type":"uint256"}],"name":"minter_burn_from","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"m_address","type":"address"},{"internalType":"uint256","name":"m_amount","type":"uint256"}],"name":"minter_mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"minters_array","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previewPPSAndTotalAssets","outputs":[{"internalType":"uint256","name":"_pricePerShare","type":"uint256"},{"internalType":"uint256","name":"_totalAssets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previewPricePerShare","outputs":[{"internalType":"uint256","name":"_newPricePerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_futureTime","type":"uint256"}],"name":"previewPricePerShareFuture","outputs":[{"internalType":"uint256","name":"_newPricePerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previewTotalAssets","outputs":[{"internalType":"uint256","name":"_newTotalAssets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_futureTime","type":"uint256"}],"name":"previewTotalAssetsFuture","outputs":[{"internalType":"uint256","name":"_newTotalAssets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerShare","outputs":[{"internalType":"uint256","name":"_pricePerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerShareIncPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerShareStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter_address","type":"address"}],"name":"removeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsCycleData","outputs":[{"components":[{"internalType":"uint40","name":"cycleEnd","type":"uint40"},{"internalType":"uint40","name":"lastSync","type":"uint40"},{"internalType":"uint216","name":"rewardCycleAmount","type":"uint216"}],"internalType":"struct LinearRewardsErc4626_2.RewardsCycleData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPricePerShareStored","type":"uint256"},{"internalType":"uint256","name":"_newPricePerShareIncPerSecond","type":"uint256"},{"internalType":"uint256","name":"_newLastSync","type":"uint256"}],"name":"setAllPricingParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPricePerShareIncPerSecond","type":"uint256"}],"name":"setPricePerShareIncPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPricePerShareStored","type":"uint256"}],"name":"setPricePerShareStored","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"storedTotalAssets","outputs":[{"internalType":"uint256","name":"_newTotalAssets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[{"internalType":"uint256","name":"_pricePerShare","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"_totalAssets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"transferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x000000000000000000000000cacd6fd266af91b8aed52accc382b4e165586e29"}