{"matchId":"646378","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2025-04-10T07:26:29Z","creationBytecode":{"onchainBytecode":"0x60a03461011c57601f19610a3538819003601f810183168401936001600160401b03939092909183861085871117610106578084926040978852833960209384918101031261011c5751926001600160a01b03841680850361011c5785519182870190811183821017610106578652600c82526b7a65726f206164647265737360a01b84830152156100ad57505050608052516109139081610122823960805181818160bc015261026b0152f35b82855192839162461bcd60e51b835280600484015283519081602485015260005b8281106100ef5750506044935080600085601f938601015201168101030190fd5b8086018201518782016044015286945081016100ce565b634e487b7160e01b600052604160045260246000fd5b600080fdfe6080604090808252600436101561001557600080fd5b600090813560e01c90816301977b571461028f575080633acb5624146102205780638c00bf6b146101f457639451fed41461004f57600080fd5b346101f15761005d366102d6565b8351939184830167ffffffffffffffff8111868210176101c4578352600a85526020947f6e6f74204d6f7270686f000000000000000000000000000000000000000000008682015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036101315750828061011460a07f7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321942094856104ff565b91878684939952808a52205581519086825287820152a251908152f35b84908685519283917f08c379a0000000000000000000000000000000000000000000000000000000008352806004840152835193846024850152825b8581106101ad57505050601f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092604480968601015201168101030190fd5b81810183015187820160440152869450820161016d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b50903461021c5760209061021460a061020c366102d6565b9190206104ff565b509051908152f35b5080fd5b50903461021c57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021c576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b905082346102d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102d257602092600435815280845220548152f35b8280fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820161016081126104415760a013610441576040805167ffffffffffffffff919060a081018381118282101761044657825273ffffffffffffffffffffffffffffffffffffffff6004358181168103610441578252602435818116810361044157602083015260443581811681036104415783830152606435908116810361044157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c91606060c094015260843560808201529501126104415780519160c08301908111838210176104465781526fffffffffffffffffffffffffffffffff9060a435828116810361044157835260c435828116810361044157602084015260e435908282168203610441578301526101043581811681036104415760608301526101243581811681036104415760808301526101443590811681036104415760a082015290565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291600082127f80000000000000000000000000000000000000000000000000000000000000008214166104b45781840514901517156104b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919091600083820193841291129080158216911516176104b457565b81519092916fffffffffffffffffffffffffffffffff91821680156000816107c357508360408401511690670de0b6b3a7640000918281029281840414901517156104b45761078f5704915b670c7d713b49da0000808413156107be575067016345785d8a00005b7ffffffffffffffffffffffffffffffffffffffffffffffffff3828ec4b626000084019384136001166104b457670de0b6b3a764000093848102908082058614901517156104b457811561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f80000000000000000000000000000000000000000000000000000000000000008214166104b4570594600052600060205260406000205491600091831560001461067a5750505050634b9a1eff8161064482955b600081121561066c57670a688906bd8b0000610475565b059082820191600084841291129080158216911516176104b45761066791610475565b059190565b6729a2241af62c0000610475565b650171268b5ad49187830292830588036107625760800151164203904282116107355790846106a99205610475565b806106bb57505081610644829561062d565b906106e1826106db6106d1869560029a976107cc565b98899205856107cc565b936104e3565b908260011b926002840503610708575060046107018593610644936104e3565b059261062d565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b610567565b9150509161054b565b6107e8906107e2670de0b6b3a764000093610807565b90610475565b05640ec41a0ddf81811290821802186301e3da5f818113908218021890565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d881126108d7576805168fd0946fc0415f8112156108b95760008112156108aa577ffffffffffffffffffffffffffffffffffffffffffffffffffb30b927e6d498d2905b67099e8db03256ce5d80928201059182029003670de0b6b3a764000090600282828002050501019060008112156000146108a3571b90565b6000031d90565b6704cf46d8192b672e9061086b565b50780931d81650c7d88b800000000000000000000000000000000090565b5060009056fea2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033000000000000000000000000bbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb","recompiledBytecode":"0x60a03461011c57601f19610a3538819003601f810183168401936001600160401b03939092909183861085871117610106578084926040978852833960209384918101031261011c5751926001600160a01b03841680850361011c5785519182870190811183821017610106578652600c82526b7a65726f206164647265737360a01b84830152156100ad57505050608052516109139081610122823960805181818160bc015261026b0152f35b82855192839162461bcd60e51b835280600484015283519081602485015260005b8281106100ef5750506044935080600085601f938601015201168101030190fd5b8086018201518782016044015286945081016100ce565b634e487b7160e01b600052604160045260246000fd5b600080fdfe6080604090808252600436101561001557600080fd5b600090813560e01c90816301977b571461028f575080633acb5624146102205780638c00bf6b146101f457639451fed41461004f57600080fd5b346101f15761005d366102d6565b8351939184830167ffffffffffffffff8111868210176101c4578352600a85526020947f6e6f74204d6f7270686f000000000000000000000000000000000000000000008682015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036101315750828061011460a07f7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321942094856104ff565b91878684939952808a52205581519086825287820152a251908152f35b84908685519283917f08c379a0000000000000000000000000000000000000000000000000000000008352806004840152835193846024850152825b8581106101ad57505050601f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092604480968601015201168101030190fd5b81810183015187820160440152869450820161016d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b50903461021c5760209061021460a061020c366102d6565b9190206104ff565b509051908152f35b5080fd5b50903461021c57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021c576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b905082346102d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102d257602092600435815280845220548152f35b8280fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820161016081126104415760a013610441576040805167ffffffffffffffff919060a081018381118282101761044657825273ffffffffffffffffffffffffffffffffffffffff6004358181168103610441578252602435818116810361044157602083015260443581811681036104415783830152606435908116810361044157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c91606060c094015260843560808201529501126104415780519160c08301908111838210176104465781526fffffffffffffffffffffffffffffffff9060a435828116810361044157835260c435828116810361044157602084015260e435908282168203610441578301526101043581811681036104415760608301526101243581811681036104415760808301526101443590811681036104415760a082015290565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291600082127f80000000000000000000000000000000000000000000000000000000000000008214166104b45781840514901517156104b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919091600083820193841291129080158216911516176104b457565b81519092916fffffffffffffffffffffffffffffffff91821680156000816107c357508360408401511690670de0b6b3a7640000918281029281840414901517156104b45761078f5704915b670c7d713b49da0000808413156107be575067016345785d8a00005b7ffffffffffffffffffffffffffffffffffffffffffffffffff3828ec4b626000084019384136001166104b457670de0b6b3a764000093848102908082058614901517156104b457811561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f80000000000000000000000000000000000000000000000000000000000000008214166104b4570594600052600060205260406000205491600091831560001461067a5750505050634b9a1eff8161064482955b600081121561066c57670a688906bd8b0000610475565b059082820191600084841291129080158216911516176104b45761066791610475565b059190565b6729a2241af62c0000610475565b650171268b5ad49187830292830588036107625760800151164203904282116107355790846106a99205610475565b806106bb57505081610644829561062d565b906106e1826106db6106d1869560029a976107cc565b98899205856107cc565b936104e3565b908260011b926002840503610708575060046107018593610644936104e3565b059261062d565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b610567565b9150509161054b565b6107e8906107e2670de0b6b3a764000093610807565b90610475565b05640ec41a0ddf81811290821802186301e3da5f818113908218021890565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d881126108d7576805168fd0946fc0415f8112156108b95760008112156108aa577ffffffffffffffffffffffffffffffffffffffffffffffffffb30b927e6d498d2905b67099e8db03256ce5d80928201059182029003670de0b6b3a764000090600282828002050501019060008112156000146108a3571b90565b6000031d90565b6704cf46d8192b672e9061086b565b50780931d81650c7d88b800000000000000000000000000000000090565b5060009056fea2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","sourceMap":"852:6304:4:-:0;;;;-1:-1:-1;;852:6304:4;;;;;;;;;;;;;-1:-1:-1;;;;;852:6304:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;852:6304:4;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;852:6304:4;;;;1556:20;302:14:6;;1612:15:4;;;;;852:6304;;;;;;;1612:15;852:6304;;;;;;;;;;;302:14:6;852:6304:4;;;302:14:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;302:14:6;;;;;;;;;;;;-1:-1:-1;302:14:6;852:6304:4;302:14:6;;;;;852:6304:4;;302:14:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;302:14:6;;;;852:6304:4;;;;-1:-1:-1;852:6304:4;;;;;-1:-1:-1;852:6304:4;;-1:-1:-1;852:6304:4;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","offset":2560}},"transformations":[{"type":"insert","offset":2613,"reason":"constructorArguments"}],"transformationValues":{"constructorArguments":"0x000000000000000000000000bbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb"}},"runtimeBytecode":{"onchainBytecode":"0x6080604090808252600436101561001557600080fd5b600090813560e01c90816301977b571461028f575080633acb5624146102205780638c00bf6b146101f457639451fed41461004f57600080fd5b346101f15761005d366102d6565b8351939184830167ffffffffffffffff8111868210176101c4578352600a85526020947f6e6f74204d6f7270686f000000000000000000000000000000000000000000008682015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000bbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb1633036101315750828061011460a07f7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321942094856104ff565b91878684939952808a52205581519086825287820152a251908152f35b84908685519283917f08c379a0000000000000000000000000000000000000000000000000000000008352806004840152835193846024850152825b8581106101ad57505050601f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092604480968601015201168101030190fd5b81810183015187820160440152869450820161016d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b50903461021c5760209061021460a061020c366102d6565b9190206104ff565b509051908152f35b5080fd5b50903461021c57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021c576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000bbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb168152f35b905082346102d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102d257602092600435815280845220548152f35b8280fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820161016081126104415760a013610441576040805167ffffffffffffffff919060a081018381118282101761044657825273ffffffffffffffffffffffffffffffffffffffff6004358181168103610441578252602435818116810361044157602083015260443581811681036104415783830152606435908116810361044157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c91606060c094015260843560808201529501126104415780519160c08301908111838210176104465781526fffffffffffffffffffffffffffffffff9060a435828116810361044157835260c435828116810361044157602084015260e435908282168203610441578301526101043581811681036104415760608301526101243581811681036104415760808301526101443590811681036104415760a082015290565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291600082127f80000000000000000000000000000000000000000000000000000000000000008214166104b45781840514901517156104b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919091600083820193841291129080158216911516176104b457565b81519092916fffffffffffffffffffffffffffffffff91821680156000816107c357508360408401511690670de0b6b3a7640000918281029281840414901517156104b45761078f5704915b670c7d713b49da0000808413156107be575067016345785d8a00005b7ffffffffffffffffffffffffffffffffffffffffffffffffff3828ec4b626000084019384136001166104b457670de0b6b3a764000093848102908082058614901517156104b457811561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f80000000000000000000000000000000000000000000000000000000000000008214166104b4570594600052600060205260406000205491600091831560001461067a5750505050634b9a1eff8161064482955b600081121561066c57670a688906bd8b0000610475565b059082820191600084841291129080158216911516176104b45761066791610475565b059190565b6729a2241af62c0000610475565b650171268b5ad49187830292830588036107625760800151164203904282116107355790846106a99205610475565b806106bb57505081610644829561062d565b906106e1826106db6106d1869560029a976107cc565b98899205856107cc565b936104e3565b908260011b926002840503610708575060046107018593610644936104e3565b059261062d565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b610567565b9150509161054b565b6107e8906107e2670de0b6b3a764000093610807565b90610475565b05640ec41a0ddf81811290821802186301e3da5f818113908218021890565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d881126108d7576805168fd0946fc0415f8112156108b95760008112156108aa577ffffffffffffffffffffffffffffffffffffffffffffffffffb30b927e6d498d2905b67099e8db03256ce5d80928201059182029003670de0b6b3a764000090600282828002050501019060008112156000146108a3571b90565b6000031d90565b6704cf46d8192b672e9061086b565b50780931d81650c7d88b800000000000000000000000000000000090565b5060009056fea2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","recompiledBytecode":"0x6080604090808252600436101561001557600080fd5b600090813560e01c90816301977b571461028f575080633acb5624146102205780638c00bf6b146101f457639451fed41461004f57600080fd5b346101f15761005d366102d6565b8351939184830167ffffffffffffffff8111868210176101c4578352600a85526020947f6e6f74204d6f7270686f000000000000000000000000000000000000000000008682015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036101315750828061011460a07f7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321942094856104ff565b91878684939952808a52205581519086825287820152a251908152f35b84908685519283917f08c379a0000000000000000000000000000000000000000000000000000000008352806004840152835193846024850152825b8581106101ad57505050601f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092604480968601015201168101030190fd5b81810183015187820160440152869450820161016d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b50903461021c5760209061021460a061020c366102d6565b9190206104ff565b509051908152f35b5080fd5b50903461021c57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021c576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b905082346102d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102d257602092600435815280845220548152f35b8280fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820161016081126104415760a013610441576040805167ffffffffffffffff919060a081018381118282101761044657825273ffffffffffffffffffffffffffffffffffffffff6004358181168103610441578252602435818116810361044157602083015260443581811681036104415783830152606435908116810361044157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c91606060c094015260843560808201529501126104415780519160c08301908111838210176104465781526fffffffffffffffffffffffffffffffff9060a435828116810361044157835260c435828116810361044157602084015260e435908282168203610441578301526101043581811681036104415760608301526101243581811681036104415760808301526101443590811681036104415760a082015290565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291600082127f80000000000000000000000000000000000000000000000000000000000000008214166104b45781840514901517156104b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919091600083820193841291129080158216911516176104b457565b81519092916fffffffffffffffffffffffffffffffff91821680156000816107c357508360408401511690670de0b6b3a7640000918281029281840414901517156104b45761078f5704915b670c7d713b49da0000808413156107be575067016345785d8a00005b7ffffffffffffffffffffffffffffffffffffffffffffffffff3828ec4b626000084019384136001166104b457670de0b6b3a764000093848102908082058614901517156104b457811561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f80000000000000000000000000000000000000000000000000000000000000008214166104b4570594600052600060205260406000205491600091831560001461067a5750505050634b9a1eff8161064482955b600081121561066c57670a688906bd8b0000610475565b059082820191600084841291129080158216911516176104b45761066791610475565b059190565b6729a2241af62c0000610475565b650171268b5ad49187830292830588036107625760800151164203904282116107355790846106a99205610475565b806106bb57505081610644829561062d565b906106e1826106db6106d1869560029a976107cc565b98899205856107cc565b936104e3565b908260011b926002840503610708575060046107018593610644936104e3565b059261062d565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b610567565b9150509161054b565b6107e8906107e2670de0b6b3a764000093610807565b90610475565b05640ec41a0ddf81811290821802186301e3da5f818113908218021890565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d881126108d7576805168fd0946fc0415f8112156108b95760008112156108aa577ffffffffffffffffffffffffffffffffffffffffffffffffffb30b927e6d498d2905b67099e8db03256ce5d80928201059182029003670de0b6b3a764000090600282828002050501019060008112156000146108a3571b90565b6000031d90565b6704cf46d8192b672e9061086b565b50780931d81650c7d88b800000000000000000000000000000000090565b5060009056fea2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","sourceMap":"852:6304:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2067:6;852:6304;2053:10;:20;412:12:6;;696:118:2;;;2187:23:4;696:118:2;2334:55:4;696:118:2;;2187:23:4;;;:::i;:::-;852:6304;;;;;;;;;;;412:12:6;852:6304:4;;;;;;412:12:6;;;852:6304:4;2334:55;852:6304;;;;;412:12:6;852:6304:4;;;;;412:12:6;;;;;;;852:6304:4;412:12:6;;;;;;;;;;;;;;;;;;;;;852:6304:4;412:12:6;852:6304:4;412:12:6;;;;;;;;852:6304:4;;412:12:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;412:12:6;;;;852:6304:4;;;;;;;;;;;;;;;;;;;;;1832:38;696:118:2;852:6304:4;;;:::i;:::-;696:118:2;;;1832:38:4;:::i;:::-;852:6304;;;;;;;;;;;;;;;;;;;;;;;;;;;;1270:31;852:6304;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;852:6304:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;-1:-1:-1;852:6304:4;;;;-1:-1:-1;852:6304:4;;;;;-1:-1:-1;852:6304:4;606:27:9;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;153:11:7;606:27:9;153:11:7;;;;;606:27:9;153:11:7;606:27:9;;;;;;;;;;;;;;;;;;;;;;;;:::o;2545:3384:4:-;852:6304;;2545:3384;;;852:6304;;;;2776:28;;-1:-1:-1;2776:28:4;;;2807:24;;;;;852:6304;;93:4:3;;852:6304:4;;;;;;;;;;;;;;;;;;2776:94;;775:9:9;2905:45:4;;;775:9:9;;;2905:143:4;153:11:7;2905:143:4;153:11:7;;;;;;;;;;93:4:3;606:27:9;;;;;;;;;;;;;;;;153:11:7;;;;;;;;;;;;;;852:6304:4;-1:-1:-1;852:6304:4;-1:-1:-1;852:6304:4;;;-1:-1:-1;852:6304:4;153:11:7;3209:22:4;-1:-1:-1;3241:22:4;3278;;3274:2512;3278:22;;;3350:53;;;;153:11:7;3417:53:4;516:5:7;3417:53:4;3274:2512;;-1:-1:-1;6326:7:4;;-1:-1:-1;;;153:11:7;516:5;:::i;:::-;153:11;606:27:9;;;;;-1:-1:-1;606:27:9;;;;;;;;;;;;;;;;516:5:7;;;:::i;:::-;153:11;5859:63:4;2545:3384;:::o;6326:97::-;153:11:7;516:5;:::i;3274:2512:4:-;153:11:7;606:27:9;;;;;;;;;;;4005:17:4;;852:6304;;3987:15;606:27:9;3987:15:4;;606:27:9;;;;153:11:7;;4063:15:4;153:11:7;;4063:15:4;:::i;:::-;4097:21;;;4238:35;;;516:5:7;4238:35:4;4093:1683;3274:2512;;4093:1683;5509:53;5699:35;5509:53;5605:57;5509:53;;;5660:1;5509:53;;;:::i;:::-;153:11:7;;;;5605:57:4;;:::i;:::-;5699:35;;:::i;:::-;606:27:9;;153:11:7;606:27:9;;5660:1:4;606:27:9;;;;;5699:57:4;5760:1;5699:57;;;516:5:7;5699:57:4;;:::i;:::-;153:11:7;4093:1683:4;3274:2512;;606:27:9;153:11:7;;;;;;;;;606:27:9;153:11:7;;;;;;;;;606:27:9;153:11:7;;;;;;;;;;;-1:-1:-1;153:11:7;;;;;-1:-1:-1;153:11:7;2905:143:4;;;2776:94;;;;;;;6814:340;516:5:7;6814:340:4;7023:29;93:4:3;6814:340:4;7023:29;:::i;:::-;516:5:7;;:::i;:::-;153:11;;428:197:8;;;;;;;;153:11:7;428:197:8;;;;;;;;6814:340:4;:::o;941:1128:10:-;413:28;1112:14;;1108:28;;692:27;1238:21;;;1234:50;;1483:1;1479:5;;1483:1;;;318:26;1478:42;;318:26;;;;;;;;;;;93:4:3;318:26:10;1915:1;318:26;;;;;;;;1974:6;1483:1;1974:6;;;1970:82;1483:1;;;318:26;1982:25;:::o;1970:82::-;1483:1;318:26;;2026;:::o;1478:42::-;318:26;1478:42;;;1234:50;1261:23;822:66;1261:23;:::o;1108:28::-;1128:8;1135:1;1128:8;:::o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","offset":2270}},"immutableReferences":{"659":[{"start":188,"length":32},{"start":619,"length":32}]},"transformations":[{"id":"659","type":"replace","offset":188,"reason":"immutable"},{"id":"659","type":"replace","offset":619,"reason":"immutable"}],"transformationValues":{"immutables":{"659":"0x000000000000000000000000bbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb"}}},"deployment":{"transactionHash":"0xed1c92b669b43f743725bc6072c4c984381466432f1ea73362883d643a270302","blockNumber":"13977152","transactionIndex":"39","deployer":"0x937Ce2d6c488b361825D2DB5e8A70e26d48afEd5"},"sources":{"src/AdaptiveCurveIrm.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {IIrm} from \"../lib/morpho-blue/src/interfaces/IIrm.sol\";\nimport {IAdaptiveCurveIrm} from \"./interfaces/IAdaptiveCurveIrm.sol\";\n\nimport {UtilsLib} from \"./libraries/UtilsLib.sol\";\nimport {ErrorsLib} from \"./libraries/ErrorsLib.sol\";\nimport {ExpLib} from \"./libraries/adaptive-curve/ExpLib.sol\";\nimport {MathLib, WAD_INT as WAD} from \"./libraries/MathLib.sol\";\nimport {ConstantsLib} from \"./libraries/adaptive-curve/ConstantsLib.sol\";\nimport {MarketParamsLib} from \"../lib/morpho-blue/src/libraries/MarketParamsLib.sol\";\nimport {Id, MarketParams, Market} from \"../lib/morpho-blue/src/interfaces/IMorpho.sol\";\nimport {MathLib as MorphoMathLib} from \"../lib/morpho-blue/src/libraries/MathLib.sol\";\n\n/// @title AdaptiveCurveIrm\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\ncontract AdaptiveCurveIrm is IAdaptiveCurveIrm {\n    using MathLib for int256;\n    using UtilsLib for int256;\n    using MorphoMathLib for uint128;\n    using MarketParamsLib for MarketParams;\n\n    /* EVENTS */\n\n    /// @notice Emitted when a borrow rate is updated.\n    event BorrowRateUpdate(Id indexed id, uint256 avgBorrowRate, uint256 rateAtTarget);\n\n    /* IMMUTABLES */\n\n    /// @inheritdoc IAdaptiveCurveIrm\n    address public immutable MORPHO;\n\n    /* STORAGE */\n\n    /// @inheritdoc IAdaptiveCurveIrm\n    mapping(Id => int256) public rateAtTarget;\n\n    /* CONSTRUCTOR */\n\n    /// @notice Constructor.\n    /// @param morpho The address of Morpho.\n    constructor(address morpho) {\n        require(morpho != address(0), ErrorsLib.ZERO_ADDRESS);\n\n        MORPHO = morpho;\n    }\n\n    /* BORROW RATES */\n\n    /// @inheritdoc IIrm\n    function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256) {\n        (uint256 avgRate,) = _borrowRate(marketParams.id(), market);\n        return avgRate;\n    }\n\n    /// @inheritdoc IIrm\n    function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256) {\n        require(msg.sender == MORPHO, ErrorsLib.NOT_MORPHO);\n\n        Id id = marketParams.id();\n\n        (uint256 avgRate, int256 endRateAtTarget) = _borrowRate(id, market);\n\n        rateAtTarget[id] = endRateAtTarget;\n\n        // Safe \"unchecked\" cast because endRateAtTarget >= 0.\n        emit BorrowRateUpdate(id, avgRate, uint256(endRateAtTarget));\n\n        return avgRate;\n    }\n\n    /// @dev Returns avgRate and endRateAtTarget.\n    /// @dev Assumes that the inputs `marketParams` and `id` match.\n    function _borrowRate(Id id, Market memory market) private view returns (uint256, int256) {\n        // Safe \"unchecked\" cast because the utilization is smaller than 1 (scaled by WAD).\n        int256 utilization =\n            int256(market.totalSupplyAssets > 0 ? market.totalBorrowAssets.wDivDown(market.totalSupplyAssets) : 0);\n\n        int256 errNormFactor = utilization > ConstantsLib.TARGET_UTILIZATION\n            ? WAD - ConstantsLib.TARGET_UTILIZATION\n            : ConstantsLib.TARGET_UTILIZATION;\n        int256 err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivToZero(errNormFactor);\n\n        int256 startRateAtTarget = rateAtTarget[id];\n\n        int256 avgRateAtTarget;\n        int256 endRateAtTarget;\n\n        if (startRateAtTarget == 0) {\n            // First interaction.\n            avgRateAtTarget = ConstantsLib.INITIAL_RATE_AT_TARGET;\n            endRateAtTarget = ConstantsLib.INITIAL_RATE_AT_TARGET;\n        } else {\n            // The speed is assumed constant between two updates, but it is in fact not constant because of interest.\n            // So the rate is always underestimated.\n            int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulToZero(err);\n            // market.lastUpdate != 0 because it is not the first interaction with this market.\n            // Safe \"unchecked\" cast because block.timestamp - market.lastUpdate <= block.timestamp <= type(int256).max.\n            int256 elapsed = int256(block.timestamp - market.lastUpdate);\n            int256 linearAdaptation = speed * elapsed;\n\n            if (linearAdaptation == 0) {\n                // If linearAdaptation == 0, avgRateAtTarget = endRateAtTarget = startRateAtTarget;\n                avgRateAtTarget = startRateAtTarget;\n                endRateAtTarget = startRateAtTarget;\n            } else {\n                // Formula of the average rate that should be returned to Morpho Blue:\n                // avg = 1/T * ∫_0^T curve(startRateAtTarget*exp(speed*x), err) dx\n                // The integral is approximated with the trapezoidal rule:\n                // avg ~= 1/T * Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / 2 * T/N\n                // Where f(x) = startRateAtTarget*exp(speed*x)\n                // avg ~= Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / (2 * N)\n                // As curve is linear in its first argument:\n                // avg ~= curve([Σ_i=1^N [f((i-1) * T/N) + f(i * T/N)] / (2 * N), err)\n                // avg ~= curve([(f(0) + f(T))/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err)\n                // avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err)\n                // With N = 2:\n                // avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + startRateAtTarget*exp(speed*T/2)] / 2, err)\n                // avg ~= curve([startRateAtTarget + endRateAtTarget + 2*startRateAtTarget*exp(speed*T/2)] / 4, err)\n                endRateAtTarget = _newRateAtTarget(startRateAtTarget, linearAdaptation);\n                int256 midRateAtTarget = _newRateAtTarget(startRateAtTarget, linearAdaptation / 2);\n                avgRateAtTarget = (startRateAtTarget + endRateAtTarget + 2 * midRateAtTarget) / 4;\n            }\n        }\n\n        // Safe \"unchecked\" cast because avgRateAtTarget >= 0.\n        return (uint256(_curve(avgRateAtTarget, err)), endRateAtTarget);\n    }\n\n    /// @dev Returns the rate for a given `_rateAtTarget` and an `err`.\n    /// The formula of the curve is the following:\n    /// r = ((1-1/C)*err + 1) * rateAtTarget if err < 0\n    ///     ((C-1)*err + 1) * rateAtTarget else.\n    function _curve(int256 _rateAtTarget, int256 err) private pure returns (int256) {\n        // Non negative because 1 - 1/C >= 0, C - 1 >= 0.\n        int256 coeff = err < 0 ? WAD - WAD.wDivToZero(ConstantsLib.CURVE_STEEPNESS) : ConstantsLib.CURVE_STEEPNESS - WAD;\n        // Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1.\n        return (coeff.wMulToZero(err) + WAD).wMulToZero(int256(_rateAtTarget));\n    }\n\n    /// @dev Returns the new rate at target, for a given `startRateAtTarget` and a given `linearAdaptation`.\n    /// The formula is: max(min(startRateAtTarget * exp(linearAdaptation), maxRateAtTarget), minRateAtTarget).\n    function _newRateAtTarget(int256 startRateAtTarget, int256 linearAdaptation) private pure returns (int256) {\n        // Non negative because MIN_RATE_AT_TARGET > 0.\n        return startRateAtTarget.wMulToZero(ExpLib.wExp(linearAdaptation)).bound(\n            ConstantsLib.MIN_RATE_AT_TARGET, ConstantsLib.MAX_RATE_AT_TARGET\n        );\n    }\n}\n"},"src/libraries/MathLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {WAD} from \"../../lib/morpho-blue/src/libraries/MathLib.sol\";\n\nint256 constant WAD_INT = int256(WAD);\n\n/// @title MathLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to manage fixed-point arithmetic on signed integers.\nlibrary MathLib {\n    /// @dev Returns the multiplication of `x` by `y` (in WAD) rounded towards 0.\n    function wMulToZero(int256 x, int256 y) internal pure returns (int256) {\n        return (x * y) / WAD_INT;\n    }\n\n    /// @dev Returns the division of `x` by `y` (in WAD) rounded towards 0.\n    function wDivToZero(int256 x, int256 y) internal pure returns (int256) {\n        return (x * WAD_INT) / y;\n    }\n}\n"},"src/libraries/UtilsLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title UtilsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library exposing helpers.\nlibrary UtilsLib {\n    /// @dev Bounds `x` between `low` and `high`.\n    /// @dev Assumes that `low` <= `high`. If it is not the case it returns `low`.\n    function bound(int256 x, int256 low, int256 high) internal pure returns (int256 z) {\n        assembly {\n            // z = min(x, high).\n            z := xor(x, mul(xor(x, high), slt(high, x)))\n            // z = max(z, low).\n            z := xor(z, mul(xor(z, low), sgt(low, z)))\n        }\n    }\n}\n"},"src/libraries/ErrorsLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ErrorsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library exposing error messages.\nlibrary ErrorsLib {\n    /// @dev Thrown when passing the zero address.\n    string internal constant ZERO_ADDRESS = \"zero address\";\n\n    /// @dev Thrown when the caller is not Morpho.\n    string internal constant NOT_MORPHO = \"not Morpho\";\n}\n"},"src/interfaces/IAdaptiveCurveIrm.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.5.0;\n\nimport {IIrm} from \"../../lib/morpho-blue/src/interfaces/IIrm.sol\";\nimport {Id} from \"../../lib/morpho-blue/src/interfaces/IMorpho.sol\";\n\n/// @title IAdaptiveCurveIrm\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Interface exposed by the AdaptiveCurveIrm.\ninterface IAdaptiveCurveIrm is IIrm {\n    /// @notice Address of Morpho.\n    function MORPHO() external view returns (address);\n\n    /// @notice Rate at target utilization.\n    /// @dev Tells the height of the curve.\n    function rateAtTarget(Id id) external view returns (int256);\n}\n"},"lib/morpho-blue/src/interfaces/IIrm.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {MarketParams, Market} from \"./IMorpho.sol\";\n\n/// @title IIrm\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Interface that Interest Rate Models (IRMs) used by Morpho must implement.\ninterface IIrm {\n    /// @notice Returns the borrow rate per second (scaled by WAD) of the market `marketParams`.\n    /// @dev Assumes that `market` corresponds to `marketParams`.\n    function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256);\n\n    /// @notice Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any\n    /// storage.\n    /// @dev Assumes that `market` corresponds to `marketParams`.\n    function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256);\n}\n"},"src/libraries/adaptive-curve/ExpLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {WAD_INT} from \"../MathLib.sol\";\n\n/// @title ExpLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to approximate the exponential function.\nlibrary ExpLib {\n    /// @dev ln(2).\n    int256 internal constant LN_2_INT = 0.693147180559945309 ether;\n\n    /// @dev ln(1e-18).\n    int256 internal constant LN_WEI_INT = -41.446531673892822312 ether;\n\n    /// @dev Above this bound, `wExp` is clipped to avoid overflowing when multiplied with 1 ether.\n    /// @dev This upper bound corresponds to: ln(type(int256).max / 1e36) (scaled by WAD, floored).\n    int256 internal constant WEXP_UPPER_BOUND = 93.859467695000404319 ether;\n\n    /// @dev The value of wExp(`WEXP_UPPER_BOUND`).\n    int256 internal constant WEXP_UPPER_VALUE = 57716089161558943949701069502944508345128.422502756744429568 ether;\n\n    /// @dev Returns an approximation of exp.\n    function wExp(int256 x) internal pure returns (int256) {\n        unchecked {\n            // If x < ln(1e-18) then exp(x) < 1e-18 so it is rounded to zero.\n            if (x < LN_WEI_INT) return 0;\n            // `wExp` is clipped to avoid overflowing when multiplied with 1 ether.\n            if (x >= WEXP_UPPER_BOUND) return WEXP_UPPER_VALUE;\n\n            // Decompose x as x = q * ln(2) + r with q an integer and -ln(2)/2 <= r <= ln(2)/2.\n            // q = x / ln(2) rounded half toward zero.\n            int256 roundingAdjustment = (x < 0) ? -(LN_2_INT / 2) : (LN_2_INT / 2);\n            // Safe unchecked because x is bounded.\n            int256 q = (x + roundingAdjustment) / LN_2_INT;\n            // Safe unchecked because |q * ln(2) - x| <= ln(2)/2.\n            int256 r = x - q * LN_2_INT;\n\n            // Compute e^r with a 2nd-order Taylor polynomial.\n            // Safe unchecked because |r| < 1e18.\n            int256 expR = WAD_INT + r + (r * r) / WAD_INT / 2;\n\n            // Return e^x = 2^q * e^r.\n            if (q >= 0) return expR << uint256(q);\n            else return expR >> uint256(-q);\n        }\n    }\n}\n"},"lib/morpho-blue/src/libraries/MathLib.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\nuint256 constant WAD = 1e18;\n\n/// @title MathLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to manage fixed-point arithmetic.\nlibrary MathLib {\n    /// @dev Returns (`x` * `y`) / `WAD` rounded down.\n    function wMulDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD);\n    }\n\n    /// @dev Returns (`x` * `WAD`) / `y` rounded down.\n    function wDivDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y);\n    }\n\n    /// @dev Returns (`x` * `WAD`) / `y` rounded up.\n    function wDivUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y);\n    }\n\n    /// @dev Returns (`x` * `y`) / `d` rounded down.\n    function mulDivDown(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {\n        return (x * y) / d;\n    }\n\n    /// @dev Returns (`x` * `y`) / `d` rounded up.\n    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {\n        return (x * y + (d - 1)) / d;\n    }\n\n    /// @dev Returns the sum of the first three non-zero terms of a Taylor expansion of e^(nx) - 1, to approximate a\n    /// continuous compound interest rate.\n    function wTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) {\n        uint256 firstTerm = x * n;\n        uint256 secondTerm = mulDivDown(firstTerm, firstTerm, 2 * WAD);\n        uint256 thirdTerm = mulDivDown(secondTerm, firstTerm, 3 * WAD);\n\n        return firstTerm + secondTerm + thirdTerm;\n    }\n}\n"},"lib/morpho-blue/src/interfaces/IMorpho.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\ntype Id is bytes32;\n\nstruct MarketParams {\n    address loanToken;\n    address collateralToken;\n    address oracle;\n    address irm;\n    uint256 lltv;\n}\n\n/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest\n/// accrual.\nstruct Position {\n    uint256 supplyShares;\n    uint128 borrowShares;\n    uint128 collateral;\n}\n\n/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last\n/// interest accrual.\nstruct Market {\n    uint128 totalSupplyAssets;\n    uint128 totalSupplyShares;\n    uint128 totalBorrowAssets;\n    uint128 totalBorrowShares;\n    uint128 lastUpdate;\n    uint128 fee;\n}\n\nstruct Authorization {\n    address authorizer;\n    address authorized;\n    bool isAuthorized;\n    uint256 nonce;\n    uint256 deadline;\n}\n\nstruct Signature {\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n\n/// @dev This interface is used for factorizing IMorphoStaticTyping and IMorpho.\n/// @dev Consider using the IMorpho interface instead of this one.\ninterface IMorphoBase {\n    /// @notice The EIP-712 domain separator.\n    /// @dev Warning: Every EIP-712 signed message based on this domain separator can be reused on another chain sharing\n    /// the same chain id because the domain separator would be the same.\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n    /// @notice The owner of the contract.\n    /// @dev It has the power to change the owner.\n    /// @dev It has the power to set fees on markets and set the fee recipient.\n    /// @dev It has the power to enable but not disable IRMs and LLTVs.\n    function owner() external view returns (address);\n\n    /// @notice The fee recipient of all markets.\n    /// @dev The recipient receives the fees of a given market through a supply position on that market.\n    function feeRecipient() external view returns (address);\n\n    /// @notice Whether the `irm` is enabled.\n    function isIrmEnabled(address irm) external view returns (bool);\n\n    /// @notice Whether the `lltv` is enabled.\n    function isLltvEnabled(uint256 lltv) external view returns (bool);\n\n    /// @notice Whether `authorized` is authorized to modify `authorizer`'s position on all markets.\n    /// @dev Anyone is authorized to modify their own positions, regardless of this variable.\n    function isAuthorized(address authorizer, address authorized) external view returns (bool);\n\n    /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures.\n    function nonce(address authorizer) external view returns (uint256);\n\n    /// @notice Sets `newOwner` as `owner` of the contract.\n    /// @dev Warning: No two-step transfer ownership.\n    /// @dev Warning: The owner can be set to the zero address.\n    function setOwner(address newOwner) external;\n\n    /// @notice Enables `irm` as a possible IRM for market creation.\n    /// @dev Warning: It is not possible to disable an IRM.\n    function enableIrm(address irm) external;\n\n    /// @notice Enables `lltv` as a possible LLTV for market creation.\n    /// @dev Warning: It is not possible to disable a LLTV.\n    function enableLltv(uint256 lltv) external;\n\n    /// @notice Sets the `newFee` for the given market `marketParams`.\n    /// @param newFee The new fee, scaled by WAD.\n    /// @dev Warning: The recipient can be the zero address.\n    function setFee(MarketParams memory marketParams, uint256 newFee) external;\n\n    /// @notice Sets `newFeeRecipient` as `feeRecipient` of the fee.\n    /// @dev Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost.\n    /// @dev Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To\n    /// ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes.\n    function setFeeRecipient(address newFeeRecipient) external;\n\n    /// @notice Creates the market `marketParams`.\n    /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees\n    /// Morpho behaves as expected:\n    /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`.\n    /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with\n    /// burn functions are not supported.\n    /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`.\n    /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount\n    /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported.\n    /// - The IRM should not re-enter Morpho.\n    /// - The oracle should return a price with the correct scaling.\n    /// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties\n    /// (funds could get stuck):\n    /// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue.\n    /// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and\n    /// `toSharesDown` overflow.\n    /// - The IRM can revert on `borrowRate`.\n    /// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest`\n    /// overflow.\n    /// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and\n    /// `liquidate` from being used under certain market conditions.\n    /// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or\n    /// the computation of `assetsRepaid` in `liquidate` overflow.\n    /// @dev The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to\n    /// the point where `totalBorrowShares` is very large and borrowing overflows.\n    function createMarket(MarketParams memory marketParams) external;\n\n    /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoSupply` function with the given `data`.\n    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the\n    /// caller is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific\n    /// amount of shares is given for full compatibility and precision.\n    /// @dev Supplying a large amount can revert for overflow.\n    /// @dev Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage.\n    /// Consider using the `assets` parameter to avoid this.\n    /// @param marketParams The market to supply assets to.\n    /// @param assets The amount of assets to supply.\n    /// @param shares The amount of shares to mint.\n    /// @param onBehalf The address that will own the increased supply position.\n    /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed.\n    /// @return assetsSupplied The amount of assets supplied.\n    /// @return sharesSupplied The amount of shares minted.\n    function supply(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        bytes memory data\n    ) external returns (uint256 assetsSupplied, uint256 sharesSupplied);\n\n    /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow.\n    /// @dev It is advised to use the `shares` input when withdrawing the full position to avoid reverts due to\n    /// conversion roundings between shares and assets.\n    /// @param marketParams The market to withdraw assets from.\n    /// @param assets The amount of assets to withdraw.\n    /// @param shares The amount of shares to burn.\n    /// @param onBehalf The address of the owner of the supply position.\n    /// @param receiver The address that will receive the withdrawn assets.\n    /// @return assetsWithdrawn The amount of assets withdrawn.\n    /// @return sharesWithdrawn The amount of shares burned.\n    function withdraw(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        address receiver\n    ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);\n\n    /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the\n    /// caller is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is\n    /// given for full compatibility and precision.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Borrowing a large amount can revert for overflow.\n    /// @dev Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage.\n    /// Consider using the `assets` parameter to avoid this.\n    /// @param marketParams The market to borrow assets from.\n    /// @param assets The amount of assets to borrow.\n    /// @param shares The amount of shares to mint.\n    /// @param onBehalf The address that will own the increased borrow position.\n    /// @param receiver The address that will receive the borrowed assets.\n    /// @return assetsBorrowed The amount of assets borrowed.\n    /// @return sharesBorrowed The amount of shares minted.\n    function borrow(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        address receiver\n    ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);\n\n    /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoReplay` function with the given `data`.\n    /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`.\n    /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow.\n    /// @dev It is advised to use the `shares` input when repaying the full position to avoid reverts due to conversion\n    /// roundings between shares and assets.\n    /// @dev An attacker can front-run a repay with a small repay making the transaction revert for underflow.\n    /// @param marketParams The market to repay assets to.\n    /// @param assets The amount of assets to repay.\n    /// @param shares The amount of shares to burn.\n    /// @param onBehalf The address of the owner of the debt position.\n    /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed.\n    /// @return assetsRepaid The amount of assets repaid.\n    /// @return sharesRepaid The amount of shares burned.\n    function repay(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        bytes memory data\n    ) external returns (uint256 assetsRepaid, uint256 sharesRepaid);\n\n    /// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoSupplyCollateral` function with the given `data`.\n    /// @dev Interest are not accrued since it's not required and it saves gas.\n    /// @dev Supplying a large amount can revert for overflow.\n    /// @param marketParams The market to supply collateral to.\n    /// @param assets The amount of collateral to supply.\n    /// @param onBehalf The address that will own the increased collateral position.\n    /// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed.\n    function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data)\n        external;\n\n    /// @notice Withdraws `assets` of collateral on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow.\n    /// @param marketParams The market to withdraw collateral from.\n    /// @param assets The amount of collateral to withdraw.\n    /// @param onBehalf The address of the owner of the collateral position.\n    /// @param receiver The address that will receive the collateral assets.\n    function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver)\n        external;\n\n    /// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the\n    /// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's\n    /// `onMorphoLiquidate` function with the given `data`.\n    /// @dev Either `seizedAssets` or `repaidShares` should be zero.\n    /// @dev Seizing more than the collateral balance will underflow and revert without any error message.\n    /// @dev Repaying more than the borrow balance will underflow and revert without any error message.\n    /// @dev An attacker can front-run a liquidation with a small repay making the transaction revert for underflow.\n    /// @param marketParams The market of the position.\n    /// @param borrower The owner of the position.\n    /// @param seizedAssets The amount of collateral to seize.\n    /// @param repaidShares The amount of shares to repay.\n    /// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed.\n    /// @return The amount of assets seized.\n    /// @return The amount of assets repaid.\n    function liquidate(\n        MarketParams memory marketParams,\n        address borrower,\n        uint256 seizedAssets,\n        uint256 repaidShares,\n        bytes memory data\n    ) external returns (uint256, uint256);\n\n    /// @notice Executes a flash loan.\n    /// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all\n    /// markets combined, plus donations).\n    /// @dev Warning: Not ERC-3156 compliant but compatibility is easily reached:\n    /// - `flashFee` is zero.\n    /// - `maxFlashLoan` is the token's balance of this contract.\n    /// - The receiver of `assets` is the caller.\n    /// @param token The token to flash loan.\n    /// @param assets The amount of assets to flash loan.\n    /// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback.\n    function flashLoan(address token, uint256 assets, bytes calldata data) external;\n\n    /// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions.\n    /// @param authorized The authorized address.\n    /// @param newIsAuthorized The new authorization status.\n    function setAuthorization(address authorized, bool newIsAuthorized) external;\n\n    /// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions.\n    /// @dev Warning: Reverts if the signature has already been submitted.\n    /// @dev The signature is malleable, but it has no impact on the security here.\n    /// @dev The nonce is passed as argument to be able to revert with a different error message.\n    /// @param authorization The `Authorization` struct.\n    /// @param signature The signature.\n    function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external;\n\n    /// @notice Accrues interest for the given market `marketParams`.\n    function accrueInterest(MarketParams memory marketParams) external;\n\n    /// @notice Returns the data stored on the different `slots`.\n    function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);\n}\n\n/// @dev This interface is inherited by Morpho so that function signatures are checked by the compiler.\n/// @dev Consider using the IMorpho interface instead of this one.\ninterface IMorphoStaticTyping is IMorphoBase {\n    /// @notice The state of the position of `user` on the market corresponding to `id`.\n    /// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest\n    /// accrual.\n    function position(Id id, address user)\n        external\n        view\n        returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);\n\n    /// @notice The state of the market corresponding to `id`.\n    /// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last interest\n    /// accrual.\n    function market(Id id)\n        external\n        view\n        returns (\n            uint128 totalSupplyAssets,\n            uint128 totalSupplyShares,\n            uint128 totalBorrowAssets,\n            uint128 totalBorrowShares,\n            uint128 lastUpdate,\n            uint128 fee\n        );\n\n    /// @notice The market params corresponding to `id`.\n    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer\n    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.\n    function idToMarketParams(Id id)\n        external\n        view\n        returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv);\n}\n\n/// @title IMorpho\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures.\ninterface IMorpho is IMorphoBase {\n    /// @notice The state of the position of `user` on the market corresponding to `id`.\n    /// @dev Warning: For `feeRecipient`, `p.supplyShares` does not contain the accrued shares since the last interest\n    /// accrual.\n    function position(Id id, address user) external view returns (Position memory p);\n\n    /// @notice The state of the market corresponding to `id`.\n    /// @dev Warning: `m.totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `m.totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `m.totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last\n    /// interest accrual.\n    function market(Id id) external view returns (Market memory m);\n\n    /// @notice The market params corresponding to `id`.\n    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer\n    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.\n    function idToMarketParams(Id id) external view returns (MarketParams memory);\n}\n"},"src/libraries/adaptive-curve/ConstantsLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ConstantsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\nlibrary ConstantsLib {\n    /// @notice Curve steepness (scaled by WAD).\n    /// @dev Curve steepness = 4.\n    int256 public constant CURVE_STEEPNESS = 4 ether;\n\n    /// @notice Adjustment speed per second (scaled by WAD).\n    /// @dev The speed is per second, so the rate moves at a speed of ADJUSTMENT_SPEED * err each second (while being\n    /// continuously compounded).\n    /// @dev Adjustment speed = 50/year.\n    int256 public constant ADJUSTMENT_SPEED = 50 ether / int256(365 days);\n\n    /// @notice Target utilization (scaled by WAD).\n    /// @dev Target utilization = 90%.\n    int256 public constant TARGET_UTILIZATION = 0.9 ether;\n\n    /// @notice Initial rate at target per second (scaled by WAD).\n    /// @dev Initial rate at target = 4% (rate between 1% and 16%).\n    int256 public constant INITIAL_RATE_AT_TARGET = 0.04 ether / int256(365 days);\n\n    /// @notice Minimum rate at target per second (scaled by WAD).\n    /// @dev Minimum rate at target = 0.1% (minimum rate = 0.025%).\n    int256 public constant MIN_RATE_AT_TARGET = 0.001 ether / int256(365 days);\n\n    /// @notice Maximum rate at target per second (scaled by WAD).\n    /// @dev Maximum rate at target = 200% (maximum rate = 800%).\n    int256 public constant MAX_RATE_AT_TARGET = 2.0 ether / int256(365 days);\n}\n"},"lib/morpho-blue/src/libraries/MarketParamsLib.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\nimport {Id, MarketParams} from \"../interfaces/IMorpho.sol\";\n\n/// @title MarketParamsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to convert a market to its id.\nlibrary MarketParamsLib {\n    /// @notice The length of the data used to compute the id of a market.\n    /// @dev The length is 5 * 32 because `MarketParams` has 5 variables of 32 bytes each.\n    uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32;\n\n    /// @notice Returns the id of the market `marketParams`.\n    function id(MarketParams memory marketParams) internal pure returns (Id marketParamsId) {\n        assembly (\"memory-safe\") {\n            marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH)\n        }\n    }\n}\n"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.19+commit.7dd6d404","compilerSettings":{"viaIR":true,"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"optimizer":{"runs":999999,"enabled":true},"evmVersion":"paris","remappings":[":ds-test/=lib/forge-std/lib/ds-test/src/",":forge-std/=lib/forge-std/src/",":morpho-blue/=lib/morpho-blue/",":solmate/=lib/solmate/src/"]},"name":"AdaptiveCurveIrm","fullyQualifiedName":"src/AdaptiveCurveIrm.sol:AdaptiveCurveIrm"},"abi":[{"type":"constructor","inputs":[{"name":"morpho","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BorrowRateUpdate","type":"event","inputs":[{"name":"id","type":"bytes32","indexed":true,"internalType":"Id"},{"name":"avgBorrowRate","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"rateAtTarget","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"MORPHO","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"borrowRate","type":"function","inputs":[{"name":"marketParams","type":"tuple","components":[{"name":"loanToken","type":"address","internalType":"address"},{"name":"collateralToken","type":"address","internalType":"address"},{"name":"oracle","type":"address","internalType":"address"},{"name":"irm","type":"address","internalType":"address"},{"name":"lltv","type":"uint256","internalType":"uint256"}],"internalType":"struct MarketParams"},{"name":"market","type":"tuple","components":[{"name":"totalSupplyAssets","type":"uint128","internalType":"uint128"},{"name":"totalSupplyShares","type":"uint128","internalType":"uint128"},{"name":"totalBorrowAssets","type":"uint128","internalType":"uint128"},{"name":"totalBorrowShares","type":"uint128","internalType":"uint128"},{"name":"lastUpdate","type":"uint128","internalType":"uint128"},{"name":"fee","type":"uint128","internalType":"uint128"}],"internalType":"struct Market"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"borrowRateView","type":"function","inputs":[{"name":"marketParams","type":"tuple","components":[{"name":"loanToken","type":"address","internalType":"address"},{"name":"collateralToken","type":"address","internalType":"address"},{"name":"oracle","type":"address","internalType":"address"},{"name":"irm","type":"address","internalType":"address"},{"name":"lltv","type":"uint256","internalType":"uint256"}],"internalType":"struct MarketParams"},{"name":"market","type":"tuple","components":[{"name":"totalSupplyAssets","type":"uint128","internalType":"uint128"},{"name":"totalSupplyShares","type":"uint128","internalType":"uint128"},{"name":"totalBorrowAssets","type":"uint128","internalType":"uint128"},{"name":"totalBorrowShares","type":"uint128","internalType":"uint128"},{"name":"lastUpdate","type":"uint128","internalType":"uint128"},{"name":"fee","type":"uint128","internalType":"uint128"}],"internalType":"struct Market"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"rateAtTarget","type":"function","inputs":[{"name":"","type":"bytes32","internalType":"Id"}],"outputs":[{"name":"","type":"int256","internalType":"int256"}],"stateMutability":"view"}],"metadata":{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"morpho","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"Id","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"avgBorrowRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rateAtTarget","type":"uint256"}],"name":"BorrowRateUpdate","type":"event"},{"inputs":[],"name":"MORPHO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"components":[{"internalType":"uint128","name":"totalSupplyAssets","type":"uint128"},{"internalType":"uint128","name":"totalSupplyShares","type":"uint128"},{"internalType":"uint128","name":"totalBorrowAssets","type":"uint128"},{"internalType":"uint128","name":"totalBorrowShares","type":"uint128"},{"internalType":"uint128","name":"lastUpdate","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct Market","name":"market","type":"tuple"}],"name":"borrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"components":[{"internalType":"uint128","name":"totalSupplyAssets","type":"uint128"},{"internalType":"uint128","name":"totalSupplyShares","type":"uint128"},{"internalType":"uint128","name":"totalBorrowAssets","type":"uint128"},{"internalType":"uint128","name":"totalBorrowShares","type":"uint128"},{"internalType":"uint128","name":"lastUpdate","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct Market","name":"market","type":"tuple"}],"name":"borrowRateView","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Id","name":"","type":"bytes32"}],"name":"rateAtTarget","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"}],"devdoc":{"author":"Morpho Labs","custom:contact":"security@morpho.org","kind":"dev","methods":{"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"details":"Assumes that `market` corresponds to `marketParams`."},"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"details":"Assumes that `market` corresponds to `marketParams`."},"constructor":{"params":{"morpho":"The address of Morpho."}}},"stateVariables":{"rateAtTarget":{"details":"Tells the height of the curve."}},"title":"AdaptiveCurveIrm","version":1},"userdoc":{"events":{"BorrowRateUpdate(bytes32,uint256,uint256)":{"notice":"Emitted when a borrow rate is updated."}},"kind":"user","methods":{"MORPHO()":{"notice":"Address of Morpho."},"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"notice":"Returns the borrow rate per second (scaled by WAD) of the market `marketParams`."},"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"notice":"Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any storage."},"constructor":{"notice":"Constructor."},"rateAtTarget(bytes32)":{"notice":"Rate at target utilization."}},"version":1}},"settings":{"compilationTarget":{"src/AdaptiveCurveIrm.sol":"AdaptiveCurveIrm"},"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":999999},"remappings":[":ds-test/=lib/forge-std/lib/ds-test/src/",":forge-std/=lib/forge-std/src/",":morpho-blue/=lib/morpho-blue/",":solmate/=lib/solmate/src/"],"viaIR":true},"sources":{"lib/morpho-blue/src/interfaces/IIrm.sol":{"keccak256":"0x0f253c03461441c47cf1813b6a68649a8e0e4983e371b79cab14c6cbbf8bbdbf","license":"GPL-2.0-or-later","urls":["bzz-raw://da67969ae58aa76488d46820dc71950af8f804f416300e851eaacafbb8b40ec0","dweb:/ipfs/QmXVMhdv1vBSizDVzMaQ9SzBTvaF6owxfYZ2JzBPHRCpDA"]},"lib/morpho-blue/src/interfaces/IMorpho.sol":{"keccak256":"0xee9fbe10e0cd31b8d4c2c2effadaf337a6c6c43c9bdb94d2cad79fdffc47a86e","license":"GPL-2.0-or-later","urls":["bzz-raw://bc94b9b24900994cba898911edf82545052e738f6c9c2a7a56589c122014d363","dweb:/ipfs/QmXp9qkTnoPoio6KvdCFnCVW6Tjfb4Kbd4zByuiwQwwmwx"]},"lib/morpho-blue/src/libraries/MarketParamsLib.sol":{"keccak256":"0x6c8e25952be253b960283e8caecf8fe3138e1b2ab0595e67055d56a3eeabeffc","license":"GPL-2.0-or-later","urls":["bzz-raw://e48bddc9a1d7e498e5ffdbf15f04e3bcb82f4ddf68cced61f753bb7ac4a50fa3","dweb:/ipfs/QmRePVj1gAnvDNV613ZRQkcZt9QGmgPeMeFBtKpyyfHDxM"]},"lib/morpho-blue/src/libraries/MathLib.sol":{"keccak256":"0xa7354cbbcecef7bc0c94b61061c4e5da75515056b8e2db65e826b00d7369744a","license":"GPL-2.0-or-later","urls":["bzz-raw://d7419c59bb906fcfa49320b68f265c3200090e5c30b194766256aee70b012e08","dweb:/ipfs/Qmbo4uaW6XYnudya4bb6RU6riWXFk5M3CWJge5XzTTaEfd"]},"src/AdaptiveCurveIrm.sol":{"keccak256":"0xd008a9ee12fcb58aa329c4640ce3763aa6cbddef76cb6773a0a2c41fe0e9a494","license":"MIT","urls":["bzz-raw://f54e7d5d9a73993d4324a446cb0b69990a3752f33317abc368bd1d81cc1ded95","dweb:/ipfs/QmbeUY625BzSW2LSdvyCvQPa5mEa3TyYcc7vYiz9W1J1nc"]},"src/interfaces/IAdaptiveCurveIrm.sol":{"keccak256":"0x007428d5e900897017c896708b6d803deebb686619c4449bf35bf605656abaa7","license":"MIT","urls":["bzz-raw://20e0864280a5e68860aa00fb76570d21a125eee4a6f0c59b9b1cc28f7d44fd3e","dweb:/ipfs/QmVNCVWdrAoBzeL5fz8XJ2ZSxwKvn7765yXUsKTRZyiL4n"]},"src/libraries/ErrorsLib.sol":{"keccak256":"0x0a15b91affc57cfc57901fac5ebf84ee7368ad52c7ac2ab63ebbdeeef2b316b4","license":"MIT","urls":["bzz-raw://5470256723d55954dc7960736e47149623ffd9c361e1ec5e46296cd0b33c1df0","dweb:/ipfs/QmT3x5Y23gLRRKneWJHtLx51rw4CCgCPC36y3KgSQen6yx"]},"src/libraries/MathLib.sol":{"keccak256":"0x9a4fa3d41b403ba556348bbff9bd19ffbf3fca47a20013013ff6fb7485764fe3","license":"MIT","urls":["bzz-raw://509b52ea3fa726254ac512282d5e00e5bbd3fe7c3335120a243cd7b2abacb90d","dweb:/ipfs/QmNzNZQvyhPuC7cfD2BxjtWm7o9LNbimiDyS2u2EqfWRPT"]},"src/libraries/UtilsLib.sol":{"keccak256":"0xd4b7d2e137bd50fd5176213b5ae9af6e7dc3fcc305ccd005734bb0158594ba4d","license":"MIT","urls":["bzz-raw://406aee7bcb2509e350f604e4baaf40ab3a99f7204750119f5c0b6b0fa16d638e","dweb:/ipfs/QmVHWVAw5mxy8fKmvS7faw9EvMqvbzJyevKaxH9Wa59wcx"]},"src/libraries/adaptive-curve/ConstantsLib.sol":{"keccak256":"0x6b6306f6e40e9388cb30cafbe92f17c53438a3db222deab85866d47eb9387d3a","license":"MIT","urls":["bzz-raw://a9f458f7b46f931f45d7af0ea51b1d836a66c7c268883b7557de908eb337f502","dweb:/ipfs/QmcFSqea9HK9dgNqoH56FV1Uxze3xU7RLZZ1soWZueqNbT"]},"src/libraries/adaptive-curve/ExpLib.sol":{"keccak256":"0x89e97de7228192324faabeca393e40d8adfcbe7864d93ffa53ba01dbbe8ec3f0","license":"MIT","urls":["bzz-raw://5a49f6c5295d23c87b841045036c08dabd8c853142eef0dd623abf3f64412ccf","dweb:/ipfs/QmVQHZP1H3xwGNa4NFa2R9U3BVUucw7N8jvRvqdD9KUp6U"]}},"version":1},"storageLayout":{"types":{"t_int256":{"label":"int256","encoding":"inplace","numberOfBytes":"32"},"t_userDefinedValueType(Id)34":{"label":"Id","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_userDefinedValueType(Id)34,t_int256)":{"key":"t_userDefinedValueType(Id)34","label":"mapping(Id => int256)","value":"t_int256","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_mapping(t_userDefinedValueType(Id)34,t_int256)","astId":665,"label":"rateAtTarget","offset":0,"contract":"src/AdaptiveCurveIrm.sol:AdaptiveCurveIrm"}]},"transientStorageLayout":null,"userdoc":{"kind":"user","events":{"BorrowRateUpdate(bytes32,uint256,uint256)":{"notice":"Emitted when a borrow rate is updated."}},"methods":{"MORPHO()":{"notice":"Address of Morpho."},"constructor":{"notice":"Constructor."},"rateAtTarget(bytes32)":{"notice":"Rate at target utilization."},"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"notice":"Returns the borrow rate per second (scaled by WAD) of the market `marketParams`."},"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"notice":"Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any storage."}},"version":1},"devdoc":{"kind":"dev","title":"AdaptiveCurveIrm","author":"Morpho Labs","methods":{"constructor":{"params":{"morpho":"The address of Morpho."}},"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"details":"Assumes that `market` corresponds to `marketParams`."},"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"details":"Assumes that `market` corresponds to `marketParams`."}},"version":1,"custom:contact":"security@morpho.org","stateVariables":{"rateAtTarget":{"details":"Tells the height of the curve."}}},"sourceIds":{"src/AdaptiveCurveIrm.sol":{"id":4},"src/libraries/MathLib.sol":{"id":7},"src/libraries/UtilsLib.sol":{"id":8},"src/libraries/ErrorsLib.sol":{"id":6},"src/interfaces/IAdaptiveCurveIrm.sol":{"id":5},"lib/morpho-blue/src/interfaces/IIrm.sol":{"id":0},"src/libraries/adaptive-curve/ExpLib.sol":{"id":10},"lib/morpho-blue/src/libraries/MathLib.sol":{"id":3},"lib/morpho-blue/src/interfaces/IMorpho.sol":{"id":1},"src/libraries/adaptive-curve/ConstantsLib.sol":{"id":9},"lib/morpho-blue/src/libraries/MarketParamsLib.sol":{"id":2}},"additionalInput":null,"stdJsonInput":{"sources":{"src/AdaptiveCurveIrm.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {IIrm} from \"../lib/morpho-blue/src/interfaces/IIrm.sol\";\nimport {IAdaptiveCurveIrm} from \"./interfaces/IAdaptiveCurveIrm.sol\";\n\nimport {UtilsLib} from \"./libraries/UtilsLib.sol\";\nimport {ErrorsLib} from \"./libraries/ErrorsLib.sol\";\nimport {ExpLib} from \"./libraries/adaptive-curve/ExpLib.sol\";\nimport {MathLib, WAD_INT as WAD} from \"./libraries/MathLib.sol\";\nimport {ConstantsLib} from \"./libraries/adaptive-curve/ConstantsLib.sol\";\nimport {MarketParamsLib} from \"../lib/morpho-blue/src/libraries/MarketParamsLib.sol\";\nimport {Id, MarketParams, Market} from \"../lib/morpho-blue/src/interfaces/IMorpho.sol\";\nimport {MathLib as MorphoMathLib} from \"../lib/morpho-blue/src/libraries/MathLib.sol\";\n\n/// @title AdaptiveCurveIrm\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\ncontract AdaptiveCurveIrm is IAdaptiveCurveIrm {\n    using MathLib for int256;\n    using UtilsLib for int256;\n    using MorphoMathLib for uint128;\n    using MarketParamsLib for MarketParams;\n\n    /* EVENTS */\n\n    /// @notice Emitted when a borrow rate is updated.\n    event BorrowRateUpdate(Id indexed id, uint256 avgBorrowRate, uint256 rateAtTarget);\n\n    /* IMMUTABLES */\n\n    /// @inheritdoc IAdaptiveCurveIrm\n    address public immutable MORPHO;\n\n    /* STORAGE */\n\n    /// @inheritdoc IAdaptiveCurveIrm\n    mapping(Id => int256) public rateAtTarget;\n\n    /* CONSTRUCTOR */\n\n    /// @notice Constructor.\n    /// @param morpho The address of Morpho.\n    constructor(address morpho) {\n        require(morpho != address(0), ErrorsLib.ZERO_ADDRESS);\n\n        MORPHO = morpho;\n    }\n\n    /* BORROW RATES */\n\n    /// @inheritdoc IIrm\n    function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256) {\n        (uint256 avgRate,) = _borrowRate(marketParams.id(), market);\n        return avgRate;\n    }\n\n    /// @inheritdoc IIrm\n    function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256) {\n        require(msg.sender == MORPHO, ErrorsLib.NOT_MORPHO);\n\n        Id id = marketParams.id();\n\n        (uint256 avgRate, int256 endRateAtTarget) = _borrowRate(id, market);\n\n        rateAtTarget[id] = endRateAtTarget;\n\n        // Safe \"unchecked\" cast because endRateAtTarget >= 0.\n        emit BorrowRateUpdate(id, avgRate, uint256(endRateAtTarget));\n\n        return avgRate;\n    }\n\n    /// @dev Returns avgRate and endRateAtTarget.\n    /// @dev Assumes that the inputs `marketParams` and `id` match.\n    function _borrowRate(Id id, Market memory market) private view returns (uint256, int256) {\n        // Safe \"unchecked\" cast because the utilization is smaller than 1 (scaled by WAD).\n        int256 utilization =\n            int256(market.totalSupplyAssets > 0 ? market.totalBorrowAssets.wDivDown(market.totalSupplyAssets) : 0);\n\n        int256 errNormFactor = utilization > ConstantsLib.TARGET_UTILIZATION\n            ? WAD - ConstantsLib.TARGET_UTILIZATION\n            : ConstantsLib.TARGET_UTILIZATION;\n        int256 err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivToZero(errNormFactor);\n\n        int256 startRateAtTarget = rateAtTarget[id];\n\n        int256 avgRateAtTarget;\n        int256 endRateAtTarget;\n\n        if (startRateAtTarget == 0) {\n            // First interaction.\n            avgRateAtTarget = ConstantsLib.INITIAL_RATE_AT_TARGET;\n            endRateAtTarget = ConstantsLib.INITIAL_RATE_AT_TARGET;\n        } else {\n            // The speed is assumed constant between two updates, but it is in fact not constant because of interest.\n            // So the rate is always underestimated.\n            int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulToZero(err);\n            // market.lastUpdate != 0 because it is not the first interaction with this market.\n            // Safe \"unchecked\" cast because block.timestamp - market.lastUpdate <= block.timestamp <= type(int256).max.\n            int256 elapsed = int256(block.timestamp - market.lastUpdate);\n            int256 linearAdaptation = speed * elapsed;\n\n            if (linearAdaptation == 0) {\n                // If linearAdaptation == 0, avgRateAtTarget = endRateAtTarget = startRateAtTarget;\n                avgRateAtTarget = startRateAtTarget;\n                endRateAtTarget = startRateAtTarget;\n            } else {\n                // Formula of the average rate that should be returned to Morpho Blue:\n                // avg = 1/T * ∫_0^T curve(startRateAtTarget*exp(speed*x), err) dx\n                // The integral is approximated with the trapezoidal rule:\n                // avg ~= 1/T * Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / 2 * T/N\n                // Where f(x) = startRateAtTarget*exp(speed*x)\n                // avg ~= Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / (2 * N)\n                // As curve is linear in its first argument:\n                // avg ~= curve([Σ_i=1^N [f((i-1) * T/N) + f(i * T/N)] / (2 * N), err)\n                // avg ~= curve([(f(0) + f(T))/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err)\n                // avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err)\n                // With N = 2:\n                // avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + startRateAtTarget*exp(speed*T/2)] / 2, err)\n                // avg ~= curve([startRateAtTarget + endRateAtTarget + 2*startRateAtTarget*exp(speed*T/2)] / 4, err)\n                endRateAtTarget = _newRateAtTarget(startRateAtTarget, linearAdaptation);\n                int256 midRateAtTarget = _newRateAtTarget(startRateAtTarget, linearAdaptation / 2);\n                avgRateAtTarget = (startRateAtTarget + endRateAtTarget + 2 * midRateAtTarget) / 4;\n            }\n        }\n\n        // Safe \"unchecked\" cast because avgRateAtTarget >= 0.\n        return (uint256(_curve(avgRateAtTarget, err)), endRateAtTarget);\n    }\n\n    /// @dev Returns the rate for a given `_rateAtTarget` and an `err`.\n    /// The formula of the curve is the following:\n    /// r = ((1-1/C)*err + 1) * rateAtTarget if err < 0\n    ///     ((C-1)*err + 1) * rateAtTarget else.\n    function _curve(int256 _rateAtTarget, int256 err) private pure returns (int256) {\n        // Non negative because 1 - 1/C >= 0, C - 1 >= 0.\n        int256 coeff = err < 0 ? WAD - WAD.wDivToZero(ConstantsLib.CURVE_STEEPNESS) : ConstantsLib.CURVE_STEEPNESS - WAD;\n        // Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1.\n        return (coeff.wMulToZero(err) + WAD).wMulToZero(int256(_rateAtTarget));\n    }\n\n    /// @dev Returns the new rate at target, for a given `startRateAtTarget` and a given `linearAdaptation`.\n    /// The formula is: max(min(startRateAtTarget * exp(linearAdaptation), maxRateAtTarget), minRateAtTarget).\n    function _newRateAtTarget(int256 startRateAtTarget, int256 linearAdaptation) private pure returns (int256) {\n        // Non negative because MIN_RATE_AT_TARGET > 0.\n        return startRateAtTarget.wMulToZero(ExpLib.wExp(linearAdaptation)).bound(\n            ConstantsLib.MIN_RATE_AT_TARGET, ConstantsLib.MAX_RATE_AT_TARGET\n        );\n    }\n}\n"},"src/libraries/MathLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {WAD} from \"../../lib/morpho-blue/src/libraries/MathLib.sol\";\n\nint256 constant WAD_INT = int256(WAD);\n\n/// @title MathLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to manage fixed-point arithmetic on signed integers.\nlibrary MathLib {\n    /// @dev Returns the multiplication of `x` by `y` (in WAD) rounded towards 0.\n    function wMulToZero(int256 x, int256 y) internal pure returns (int256) {\n        return (x * y) / WAD_INT;\n    }\n\n    /// @dev Returns the division of `x` by `y` (in WAD) rounded towards 0.\n    function wDivToZero(int256 x, int256 y) internal pure returns (int256) {\n        return (x * WAD_INT) / y;\n    }\n}\n"},"src/libraries/UtilsLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title UtilsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library exposing helpers.\nlibrary UtilsLib {\n    /// @dev Bounds `x` between `low` and `high`.\n    /// @dev Assumes that `low` <= `high`. If it is not the case it returns `low`.\n    function bound(int256 x, int256 low, int256 high) internal pure returns (int256 z) {\n        assembly {\n            // z = min(x, high).\n            z := xor(x, mul(xor(x, high), slt(high, x)))\n            // z = max(z, low).\n            z := xor(z, mul(xor(z, low), sgt(low, z)))\n        }\n    }\n}\n"},"src/libraries/ErrorsLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ErrorsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library exposing error messages.\nlibrary ErrorsLib {\n    /// @dev Thrown when passing the zero address.\n    string internal constant ZERO_ADDRESS = \"zero address\";\n\n    /// @dev Thrown when the caller is not Morpho.\n    string internal constant NOT_MORPHO = \"not Morpho\";\n}\n"},"src/interfaces/IAdaptiveCurveIrm.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.5.0;\n\nimport {IIrm} from \"../../lib/morpho-blue/src/interfaces/IIrm.sol\";\nimport {Id} from \"../../lib/morpho-blue/src/interfaces/IMorpho.sol\";\n\n/// @title IAdaptiveCurveIrm\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Interface exposed by the AdaptiveCurveIrm.\ninterface IAdaptiveCurveIrm is IIrm {\n    /// @notice Address of Morpho.\n    function MORPHO() external view returns (address);\n\n    /// @notice Rate at target utilization.\n    /// @dev Tells the height of the curve.\n    function rateAtTarget(Id id) external view returns (int256);\n}\n"},"lib/morpho-blue/src/interfaces/IIrm.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {MarketParams, Market} from \"./IMorpho.sol\";\n\n/// @title IIrm\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Interface that Interest Rate Models (IRMs) used by Morpho must implement.\ninterface IIrm {\n    /// @notice Returns the borrow rate per second (scaled by WAD) of the market `marketParams`.\n    /// @dev Assumes that `market` corresponds to `marketParams`.\n    function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256);\n\n    /// @notice Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any\n    /// storage.\n    /// @dev Assumes that `market` corresponds to `marketParams`.\n    function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256);\n}\n"},"src/libraries/adaptive-curve/ExpLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {WAD_INT} from \"../MathLib.sol\";\n\n/// @title ExpLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to approximate the exponential function.\nlibrary ExpLib {\n    /// @dev ln(2).\n    int256 internal constant LN_2_INT = 0.693147180559945309 ether;\n\n    /// @dev ln(1e-18).\n    int256 internal constant LN_WEI_INT = -41.446531673892822312 ether;\n\n    /// @dev Above this bound, `wExp` is clipped to avoid overflowing when multiplied with 1 ether.\n    /// @dev This upper bound corresponds to: ln(type(int256).max / 1e36) (scaled by WAD, floored).\n    int256 internal constant WEXP_UPPER_BOUND = 93.859467695000404319 ether;\n\n    /// @dev The value of wExp(`WEXP_UPPER_BOUND`).\n    int256 internal constant WEXP_UPPER_VALUE = 57716089161558943949701069502944508345128.422502756744429568 ether;\n\n    /// @dev Returns an approximation of exp.\n    function wExp(int256 x) internal pure returns (int256) {\n        unchecked {\n            // If x < ln(1e-18) then exp(x) < 1e-18 so it is rounded to zero.\n            if (x < LN_WEI_INT) return 0;\n            // `wExp` is clipped to avoid overflowing when multiplied with 1 ether.\n            if (x >= WEXP_UPPER_BOUND) return WEXP_UPPER_VALUE;\n\n            // Decompose x as x = q * ln(2) + r with q an integer and -ln(2)/2 <= r <= ln(2)/2.\n            // q = x / ln(2) rounded half toward zero.\n            int256 roundingAdjustment = (x < 0) ? -(LN_2_INT / 2) : (LN_2_INT / 2);\n            // Safe unchecked because x is bounded.\n            int256 q = (x + roundingAdjustment) / LN_2_INT;\n            // Safe unchecked because |q * ln(2) - x| <= ln(2)/2.\n            int256 r = x - q * LN_2_INT;\n\n            // Compute e^r with a 2nd-order Taylor polynomial.\n            // Safe unchecked because |r| < 1e18.\n            int256 expR = WAD_INT + r + (r * r) / WAD_INT / 2;\n\n            // Return e^x = 2^q * e^r.\n            if (q >= 0) return expR << uint256(q);\n            else return expR >> uint256(-q);\n        }\n    }\n}\n"},"lib/morpho-blue/src/libraries/MathLib.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\nuint256 constant WAD = 1e18;\n\n/// @title MathLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to manage fixed-point arithmetic.\nlibrary MathLib {\n    /// @dev Returns (`x` * `y`) / `WAD` rounded down.\n    function wMulDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD);\n    }\n\n    /// @dev Returns (`x` * `WAD`) / `y` rounded down.\n    function wDivDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y);\n    }\n\n    /// @dev Returns (`x` * `WAD`) / `y` rounded up.\n    function wDivUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y);\n    }\n\n    /// @dev Returns (`x` * `y`) / `d` rounded down.\n    function mulDivDown(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {\n        return (x * y) / d;\n    }\n\n    /// @dev Returns (`x` * `y`) / `d` rounded up.\n    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {\n        return (x * y + (d - 1)) / d;\n    }\n\n    /// @dev Returns the sum of the first three non-zero terms of a Taylor expansion of e^(nx) - 1, to approximate a\n    /// continuous compound interest rate.\n    function wTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) {\n        uint256 firstTerm = x * n;\n        uint256 secondTerm = mulDivDown(firstTerm, firstTerm, 2 * WAD);\n        uint256 thirdTerm = mulDivDown(secondTerm, firstTerm, 3 * WAD);\n\n        return firstTerm + secondTerm + thirdTerm;\n    }\n}\n"},"lib/morpho-blue/src/interfaces/IMorpho.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\ntype Id is bytes32;\n\nstruct MarketParams {\n    address loanToken;\n    address collateralToken;\n    address oracle;\n    address irm;\n    uint256 lltv;\n}\n\n/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest\n/// accrual.\nstruct Position {\n    uint256 supplyShares;\n    uint128 borrowShares;\n    uint128 collateral;\n}\n\n/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last\n/// interest accrual.\nstruct Market {\n    uint128 totalSupplyAssets;\n    uint128 totalSupplyShares;\n    uint128 totalBorrowAssets;\n    uint128 totalBorrowShares;\n    uint128 lastUpdate;\n    uint128 fee;\n}\n\nstruct Authorization {\n    address authorizer;\n    address authorized;\n    bool isAuthorized;\n    uint256 nonce;\n    uint256 deadline;\n}\n\nstruct Signature {\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n\n/// @dev This interface is used for factorizing IMorphoStaticTyping and IMorpho.\n/// @dev Consider using the IMorpho interface instead of this one.\ninterface IMorphoBase {\n    /// @notice The EIP-712 domain separator.\n    /// @dev Warning: Every EIP-712 signed message based on this domain separator can be reused on another chain sharing\n    /// the same chain id because the domain separator would be the same.\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n    /// @notice The owner of the contract.\n    /// @dev It has the power to change the owner.\n    /// @dev It has the power to set fees on markets and set the fee recipient.\n    /// @dev It has the power to enable but not disable IRMs and LLTVs.\n    function owner() external view returns (address);\n\n    /// @notice The fee recipient of all markets.\n    /// @dev The recipient receives the fees of a given market through a supply position on that market.\n    function feeRecipient() external view returns (address);\n\n    /// @notice Whether the `irm` is enabled.\n    function isIrmEnabled(address irm) external view returns (bool);\n\n    /// @notice Whether the `lltv` is enabled.\n    function isLltvEnabled(uint256 lltv) external view returns (bool);\n\n    /// @notice Whether `authorized` is authorized to modify `authorizer`'s position on all markets.\n    /// @dev Anyone is authorized to modify their own positions, regardless of this variable.\n    function isAuthorized(address authorizer, address authorized) external view returns (bool);\n\n    /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures.\n    function nonce(address authorizer) external view returns (uint256);\n\n    /// @notice Sets `newOwner` as `owner` of the contract.\n    /// @dev Warning: No two-step transfer ownership.\n    /// @dev Warning: The owner can be set to the zero address.\n    function setOwner(address newOwner) external;\n\n    /// @notice Enables `irm` as a possible IRM for market creation.\n    /// @dev Warning: It is not possible to disable an IRM.\n    function enableIrm(address irm) external;\n\n    /// @notice Enables `lltv` as a possible LLTV for market creation.\n    /// @dev Warning: It is not possible to disable a LLTV.\n    function enableLltv(uint256 lltv) external;\n\n    /// @notice Sets the `newFee` for the given market `marketParams`.\n    /// @param newFee The new fee, scaled by WAD.\n    /// @dev Warning: The recipient can be the zero address.\n    function setFee(MarketParams memory marketParams, uint256 newFee) external;\n\n    /// @notice Sets `newFeeRecipient` as `feeRecipient` of the fee.\n    /// @dev Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost.\n    /// @dev Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To\n    /// ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes.\n    function setFeeRecipient(address newFeeRecipient) external;\n\n    /// @notice Creates the market `marketParams`.\n    /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees\n    /// Morpho behaves as expected:\n    /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`.\n    /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with\n    /// burn functions are not supported.\n    /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`.\n    /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount\n    /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported.\n    /// - The IRM should not re-enter Morpho.\n    /// - The oracle should return a price with the correct scaling.\n    /// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties\n    /// (funds could get stuck):\n    /// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue.\n    /// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and\n    /// `toSharesDown` overflow.\n    /// - The IRM can revert on `borrowRate`.\n    /// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest`\n    /// overflow.\n    /// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and\n    /// `liquidate` from being used under certain market conditions.\n    /// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or\n    /// the computation of `assetsRepaid` in `liquidate` overflow.\n    /// @dev The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to\n    /// the point where `totalBorrowShares` is very large and borrowing overflows.\n    function createMarket(MarketParams memory marketParams) external;\n\n    /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoSupply` function with the given `data`.\n    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the\n    /// caller is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific\n    /// amount of shares is given for full compatibility and precision.\n    /// @dev Supplying a large amount can revert for overflow.\n    /// @dev Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage.\n    /// Consider using the `assets` parameter to avoid this.\n    /// @param marketParams The market to supply assets to.\n    /// @param assets The amount of assets to supply.\n    /// @param shares The amount of shares to mint.\n    /// @param onBehalf The address that will own the increased supply position.\n    /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed.\n    /// @return assetsSupplied The amount of assets supplied.\n    /// @return sharesSupplied The amount of shares minted.\n    function supply(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        bytes memory data\n    ) external returns (uint256 assetsSupplied, uint256 sharesSupplied);\n\n    /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow.\n    /// @dev It is advised to use the `shares` input when withdrawing the full position to avoid reverts due to\n    /// conversion roundings between shares and assets.\n    /// @param marketParams The market to withdraw assets from.\n    /// @param assets The amount of assets to withdraw.\n    /// @param shares The amount of shares to burn.\n    /// @param onBehalf The address of the owner of the supply position.\n    /// @param receiver The address that will receive the withdrawn assets.\n    /// @return assetsWithdrawn The amount of assets withdrawn.\n    /// @return sharesWithdrawn The amount of shares burned.\n    function withdraw(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        address receiver\n    ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);\n\n    /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the\n    /// caller is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is\n    /// given for full compatibility and precision.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Borrowing a large amount can revert for overflow.\n    /// @dev Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage.\n    /// Consider using the `assets` parameter to avoid this.\n    /// @param marketParams The market to borrow assets from.\n    /// @param assets The amount of assets to borrow.\n    /// @param shares The amount of shares to mint.\n    /// @param onBehalf The address that will own the increased borrow position.\n    /// @param receiver The address that will receive the borrowed assets.\n    /// @return assetsBorrowed The amount of assets borrowed.\n    /// @return sharesBorrowed The amount of shares minted.\n    function borrow(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        address receiver\n    ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);\n\n    /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoReplay` function with the given `data`.\n    /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`.\n    /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow.\n    /// @dev It is advised to use the `shares` input when repaying the full position to avoid reverts due to conversion\n    /// roundings between shares and assets.\n    /// @dev An attacker can front-run a repay with a small repay making the transaction revert for underflow.\n    /// @param marketParams The market to repay assets to.\n    /// @param assets The amount of assets to repay.\n    /// @param shares The amount of shares to burn.\n    /// @param onBehalf The address of the owner of the debt position.\n    /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed.\n    /// @return assetsRepaid The amount of assets repaid.\n    /// @return sharesRepaid The amount of shares burned.\n    function repay(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        bytes memory data\n    ) external returns (uint256 assetsRepaid, uint256 sharesRepaid);\n\n    /// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoSupplyCollateral` function with the given `data`.\n    /// @dev Interest are not accrued since it's not required and it saves gas.\n    /// @dev Supplying a large amount can revert for overflow.\n    /// @param marketParams The market to supply collateral to.\n    /// @param assets The amount of collateral to supply.\n    /// @param onBehalf The address that will own the increased collateral position.\n    /// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed.\n    function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data)\n        external;\n\n    /// @notice Withdraws `assets` of collateral on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow.\n    /// @param marketParams The market to withdraw collateral from.\n    /// @param assets The amount of collateral to withdraw.\n    /// @param onBehalf The address of the owner of the collateral position.\n    /// @param receiver The address that will receive the collateral assets.\n    function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver)\n        external;\n\n    /// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the\n    /// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's\n    /// `onMorphoLiquidate` function with the given `data`.\n    /// @dev Either `seizedAssets` or `repaidShares` should be zero.\n    /// @dev Seizing more than the collateral balance will underflow and revert without any error message.\n    /// @dev Repaying more than the borrow balance will underflow and revert without any error message.\n    /// @dev An attacker can front-run a liquidation with a small repay making the transaction revert for underflow.\n    /// @param marketParams The market of the position.\n    /// @param borrower The owner of the position.\n    /// @param seizedAssets The amount of collateral to seize.\n    /// @param repaidShares The amount of shares to repay.\n    /// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed.\n    /// @return The amount of assets seized.\n    /// @return The amount of assets repaid.\n    function liquidate(\n        MarketParams memory marketParams,\n        address borrower,\n        uint256 seizedAssets,\n        uint256 repaidShares,\n        bytes memory data\n    ) external returns (uint256, uint256);\n\n    /// @notice Executes a flash loan.\n    /// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all\n    /// markets combined, plus donations).\n    /// @dev Warning: Not ERC-3156 compliant but compatibility is easily reached:\n    /// - `flashFee` is zero.\n    /// - `maxFlashLoan` is the token's balance of this contract.\n    /// - The receiver of `assets` is the caller.\n    /// @param token The token to flash loan.\n    /// @param assets The amount of assets to flash loan.\n    /// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback.\n    function flashLoan(address token, uint256 assets, bytes calldata data) external;\n\n    /// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions.\n    /// @param authorized The authorized address.\n    /// @param newIsAuthorized The new authorization status.\n    function setAuthorization(address authorized, bool newIsAuthorized) external;\n\n    /// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions.\n    /// @dev Warning: Reverts if the signature has already been submitted.\n    /// @dev The signature is malleable, but it has no impact on the security here.\n    /// @dev The nonce is passed as argument to be able to revert with a different error message.\n    /// @param authorization The `Authorization` struct.\n    /// @param signature The signature.\n    function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external;\n\n    /// @notice Accrues interest for the given market `marketParams`.\n    function accrueInterest(MarketParams memory marketParams) external;\n\n    /// @notice Returns the data stored on the different `slots`.\n    function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);\n}\n\n/// @dev This interface is inherited by Morpho so that function signatures are checked by the compiler.\n/// @dev Consider using the IMorpho interface instead of this one.\ninterface IMorphoStaticTyping is IMorphoBase {\n    /// @notice The state of the position of `user` on the market corresponding to `id`.\n    /// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest\n    /// accrual.\n    function position(Id id, address user)\n        external\n        view\n        returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);\n\n    /// @notice The state of the market corresponding to `id`.\n    /// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last interest\n    /// accrual.\n    function market(Id id)\n        external\n        view\n        returns (\n            uint128 totalSupplyAssets,\n            uint128 totalSupplyShares,\n            uint128 totalBorrowAssets,\n            uint128 totalBorrowShares,\n            uint128 lastUpdate,\n            uint128 fee\n        );\n\n    /// @notice The market params corresponding to `id`.\n    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer\n    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.\n    function idToMarketParams(Id id)\n        external\n        view\n        returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv);\n}\n\n/// @title IMorpho\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures.\ninterface IMorpho is IMorphoBase {\n    /// @notice The state of the position of `user` on the market corresponding to `id`.\n    /// @dev Warning: For `feeRecipient`, `p.supplyShares` does not contain the accrued shares since the last interest\n    /// accrual.\n    function position(Id id, address user) external view returns (Position memory p);\n\n    /// @notice The state of the market corresponding to `id`.\n    /// @dev Warning: `m.totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `m.totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `m.totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last\n    /// interest accrual.\n    function market(Id id) external view returns (Market memory m);\n\n    /// @notice The market params corresponding to `id`.\n    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer\n    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.\n    function idToMarketParams(Id id) external view returns (MarketParams memory);\n}\n"},"src/libraries/adaptive-curve/ConstantsLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ConstantsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\nlibrary ConstantsLib {\n    /// @notice Curve steepness (scaled by WAD).\n    /// @dev Curve steepness = 4.\n    int256 public constant CURVE_STEEPNESS = 4 ether;\n\n    /// @notice Adjustment speed per second (scaled by WAD).\n    /// @dev The speed is per second, so the rate moves at a speed of ADJUSTMENT_SPEED * err each second (while being\n    /// continuously compounded).\n    /// @dev Adjustment speed = 50/year.\n    int256 public constant ADJUSTMENT_SPEED = 50 ether / int256(365 days);\n\n    /// @notice Target utilization (scaled by WAD).\n    /// @dev Target utilization = 90%.\n    int256 public constant TARGET_UTILIZATION = 0.9 ether;\n\n    /// @notice Initial rate at target per second (scaled by WAD).\n    /// @dev Initial rate at target = 4% (rate between 1% and 16%).\n    int256 public constant INITIAL_RATE_AT_TARGET = 0.04 ether / int256(365 days);\n\n    /// @notice Minimum rate at target per second (scaled by WAD).\n    /// @dev Minimum rate at target = 0.1% (minimum rate = 0.025%).\n    int256 public constant MIN_RATE_AT_TARGET = 0.001 ether / int256(365 days);\n\n    /// @notice Maximum rate at target per second (scaled by WAD).\n    /// @dev Maximum rate at target = 200% (maximum rate = 800%).\n    int256 public constant MAX_RATE_AT_TARGET = 2.0 ether / int256(365 days);\n}\n"},"lib/morpho-blue/src/libraries/MarketParamsLib.sol":{"content":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\nimport {Id, MarketParams} from \"../interfaces/IMorpho.sol\";\n\n/// @title MarketParamsLib\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @notice Library to convert a market to its id.\nlibrary MarketParamsLib {\n    /// @notice The length of the data used to compute the id of a market.\n    /// @dev The length is 5 * 32 because `MarketParams` has 5 variables of 32 bytes each.\n    uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32;\n\n    /// @notice Returns the id of the market `marketParams`.\n    function id(MarketParams memory marketParams) internal pure returns (Id marketParamsId) {\n        assembly (\"memory-safe\") {\n            marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH)\n        }\n    }\n}\n"}},"language":"Solidity","settings":{"viaIR":true,"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"optimizer":{"runs":999999,"enabled":true},"evmVersion":"paris","remappings":[":ds-test/=lib/forge-std/lib/ds-test/src/",":forge-std/=lib/forge-std/src/",":morpho-blue/=lib/morpho-blue/",":solmate/=lib/solmate/src/"]}},"stdJsonOutput":{"sources":{"src/AdaptiveCurveIrm.sol":{"id":4},"src/libraries/MathLib.sol":{"id":7},"src/libraries/UtilsLib.sol":{"id":8},"src/libraries/ErrorsLib.sol":{"id":6},"src/interfaces/IAdaptiveCurveIrm.sol":{"id":5},"lib/morpho-blue/src/interfaces/IIrm.sol":{"id":0},"src/libraries/adaptive-curve/ExpLib.sol":{"id":10},"lib/morpho-blue/src/libraries/MathLib.sol":{"id":3},"lib/morpho-blue/src/interfaces/IMorpho.sol":{"id":1},"src/libraries/adaptive-curve/ConstantsLib.sol":{"id":9},"lib/morpho-blue/src/libraries/MarketParamsLib.sol":{"id":2}},"contracts":{"src/AdaptiveCurveIrm.sol":{"AdaptiveCurveIrm":{"abi":[{"type":"constructor","inputs":[{"name":"morpho","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BorrowRateUpdate","type":"event","inputs":[{"name":"id","type":"bytes32","indexed":true,"internalType":"Id"},{"name":"avgBorrowRate","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"rateAtTarget","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"MORPHO","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"borrowRate","type":"function","inputs":[{"name":"marketParams","type":"tuple","components":[{"name":"loanToken","type":"address","internalType":"address"},{"name":"collateralToken","type":"address","internalType":"address"},{"name":"oracle","type":"address","internalType":"address"},{"name":"irm","type":"address","internalType":"address"},{"name":"lltv","type":"uint256","internalType":"uint256"}],"internalType":"struct MarketParams"},{"name":"market","type":"tuple","components":[{"name":"totalSupplyAssets","type":"uint128","internalType":"uint128"},{"name":"totalSupplyShares","type":"uint128","internalType":"uint128"},{"name":"totalBorrowAssets","type":"uint128","internalType":"uint128"},{"name":"totalBorrowShares","type":"uint128","internalType":"uint128"},{"name":"lastUpdate","type":"uint128","internalType":"uint128"},{"name":"fee","type":"uint128","internalType":"uint128"}],"internalType":"struct Market"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"borrowRateView","type":"function","inputs":[{"name":"marketParams","type":"tuple","components":[{"name":"loanToken","type":"address","internalType":"address"},{"name":"collateralToken","type":"address","internalType":"address"},{"name":"oracle","type":"address","internalType":"address"},{"name":"irm","type":"address","internalType":"address"},{"name":"lltv","type":"uint256","internalType":"uint256"}],"internalType":"struct MarketParams"},{"name":"market","type":"tuple","components":[{"name":"totalSupplyAssets","type":"uint128","internalType":"uint128"},{"name":"totalSupplyShares","type":"uint128","internalType":"uint128"},{"name":"totalBorrowAssets","type":"uint128","internalType":"uint128"},{"name":"totalBorrowShares","type":"uint128","internalType":"uint128"},{"name":"lastUpdate","type":"uint128","internalType":"uint128"},{"name":"fee","type":"uint128","internalType":"uint128"}],"internalType":"struct Market"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"rateAtTarget","type":"function","inputs":[{"name":"","type":"bytes32","internalType":"Id"}],"outputs":[{"name":"","type":"int256","internalType":"int256"}],"stateMutability":"view"}],"metadata":"{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"morpho\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"Id\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"avgBorrowRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rateAtTarget\",\"type\":\"uint256\"}],\"name\":\"BorrowRateUpdate\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MORPHO\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"loanToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"irm\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"lltv\",\"type\":\"uint256\"}],\"internalType\":\"struct MarketParams\",\"name\":\"marketParams\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"totalSupplyAssets\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"totalSupplyShares\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"totalBorrowAssets\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"totalBorrowShares\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"lastUpdate\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"fee\",\"type\":\"uint128\"}],\"internalType\":\"struct Market\",\"name\":\"market\",\"type\":\"tuple\"}],\"name\":\"borrowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"loanToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"irm\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"lltv\",\"type\":\"uint256\"}],\"internalType\":\"struct MarketParams\",\"name\":\"marketParams\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"totalSupplyAssets\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"totalSupplyShares\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"totalBorrowAssets\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"totalBorrowShares\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"lastUpdate\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"fee\",\"type\":\"uint128\"}],\"internalType\":\"struct Market\",\"name\":\"market\",\"type\":\"tuple\"}],\"name\":\"borrowRateView\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"Id\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"rateAtTarget\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Morpho Labs\",\"custom:contact\":\"security@morpho.org\",\"kind\":\"dev\",\"methods\":{\"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))\":{\"details\":\"Assumes that `market` corresponds to `marketParams`.\"},\"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))\":{\"details\":\"Assumes that `market` corresponds to `marketParams`.\"},\"constructor\":{\"params\":{\"morpho\":\"The address of Morpho.\"}}},\"stateVariables\":{\"rateAtTarget\":{\"details\":\"Tells the height of the curve.\"}},\"title\":\"AdaptiveCurveIrm\",\"version\":1},\"userdoc\":{\"events\":{\"BorrowRateUpdate(bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a borrow rate is updated.\"}},\"kind\":\"user\",\"methods\":{\"MORPHO()\":{\"notice\":\"Address of Morpho.\"},\"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))\":{\"notice\":\"Returns the borrow rate per second (scaled by WAD) of the market `marketParams`.\"},\"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))\":{\"notice\":\"Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any storage.\"},\"constructor\":{\"notice\":\"Constructor.\"},\"rateAtTarget(bytes32)\":{\"notice\":\"Rate at target utilization.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/AdaptiveCurveIrm.sol\":\"AdaptiveCurveIrm\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":morpho-blue/=lib/morpho-blue/\",\":solmate/=lib/solmate/src/\"],\"viaIR\":true},\"sources\":{\"lib/morpho-blue/src/interfaces/IIrm.sol\":{\"keccak256\":\"0x0f253c03461441c47cf1813b6a68649a8e0e4983e371b79cab14c6cbbf8bbdbf\",\"license\":\"GPL-2.0-or-later\",\"urls\":[\"bzz-raw://da67969ae58aa76488d46820dc71950af8f804f416300e851eaacafbb8b40ec0\",\"dweb:/ipfs/QmXVMhdv1vBSizDVzMaQ9SzBTvaF6owxfYZ2JzBPHRCpDA\"]},\"lib/morpho-blue/src/interfaces/IMorpho.sol\":{\"keccak256\":\"0xee9fbe10e0cd31b8d4c2c2effadaf337a6c6c43c9bdb94d2cad79fdffc47a86e\",\"license\":\"GPL-2.0-or-later\",\"urls\":[\"bzz-raw://bc94b9b24900994cba898911edf82545052e738f6c9c2a7a56589c122014d363\",\"dweb:/ipfs/QmXp9qkTnoPoio6KvdCFnCVW6Tjfb4Kbd4zByuiwQwwmwx\"]},\"lib/morpho-blue/src/libraries/MarketParamsLib.sol\":{\"keccak256\":\"0x6c8e25952be253b960283e8caecf8fe3138e1b2ab0595e67055d56a3eeabeffc\",\"license\":\"GPL-2.0-or-later\",\"urls\":[\"bzz-raw://e48bddc9a1d7e498e5ffdbf15f04e3bcb82f4ddf68cced61f753bb7ac4a50fa3\",\"dweb:/ipfs/QmRePVj1gAnvDNV613ZRQkcZt9QGmgPeMeFBtKpyyfHDxM\"]},\"lib/morpho-blue/src/libraries/MathLib.sol\":{\"keccak256\":\"0xa7354cbbcecef7bc0c94b61061c4e5da75515056b8e2db65e826b00d7369744a\",\"license\":\"GPL-2.0-or-later\",\"urls\":[\"bzz-raw://d7419c59bb906fcfa49320b68f265c3200090e5c30b194766256aee70b012e08\",\"dweb:/ipfs/Qmbo4uaW6XYnudya4bb6RU6riWXFk5M3CWJge5XzTTaEfd\"]},\"src/AdaptiveCurveIrm.sol\":{\"keccak256\":\"0xd008a9ee12fcb58aa329c4640ce3763aa6cbddef76cb6773a0a2c41fe0e9a494\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f54e7d5d9a73993d4324a446cb0b69990a3752f33317abc368bd1d81cc1ded95\",\"dweb:/ipfs/QmbeUY625BzSW2LSdvyCvQPa5mEa3TyYcc7vYiz9W1J1nc\"]},\"src/interfaces/IAdaptiveCurveIrm.sol\":{\"keccak256\":\"0x007428d5e900897017c896708b6d803deebb686619c4449bf35bf605656abaa7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://20e0864280a5e68860aa00fb76570d21a125eee4a6f0c59b9b1cc28f7d44fd3e\",\"dweb:/ipfs/QmVNCVWdrAoBzeL5fz8XJ2ZSxwKvn7765yXUsKTRZyiL4n\"]},\"src/libraries/ErrorsLib.sol\":{\"keccak256\":\"0x0a15b91affc57cfc57901fac5ebf84ee7368ad52c7ac2ab63ebbdeeef2b316b4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5470256723d55954dc7960736e47149623ffd9c361e1ec5e46296cd0b33c1df0\",\"dweb:/ipfs/QmT3x5Y23gLRRKneWJHtLx51rw4CCgCPC36y3KgSQen6yx\"]},\"src/libraries/MathLib.sol\":{\"keccak256\":\"0x9a4fa3d41b403ba556348bbff9bd19ffbf3fca47a20013013ff6fb7485764fe3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://509b52ea3fa726254ac512282d5e00e5bbd3fe7c3335120a243cd7b2abacb90d\",\"dweb:/ipfs/QmNzNZQvyhPuC7cfD2BxjtWm7o9LNbimiDyS2u2EqfWRPT\"]},\"src/libraries/UtilsLib.sol\":{\"keccak256\":\"0xd4b7d2e137bd50fd5176213b5ae9af6e7dc3fcc305ccd005734bb0158594ba4d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://406aee7bcb2509e350f604e4baaf40ab3a99f7204750119f5c0b6b0fa16d638e\",\"dweb:/ipfs/QmVHWVAw5mxy8fKmvS7faw9EvMqvbzJyevKaxH9Wa59wcx\"]},\"src/libraries/adaptive-curve/ConstantsLib.sol\":{\"keccak256\":\"0x6b6306f6e40e9388cb30cafbe92f17c53438a3db222deab85866d47eb9387d3a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a9f458f7b46f931f45d7af0ea51b1d836a66c7c268883b7557de908eb337f502\",\"dweb:/ipfs/QmcFSqea9HK9dgNqoH56FV1Uxze3xU7RLZZ1soWZueqNbT\"]},\"src/libraries/adaptive-curve/ExpLib.sol\":{\"keccak256\":\"0x89e97de7228192324faabeca393e40d8adfcbe7864d93ffa53ba01dbbe8ec3f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a49f6c5295d23c87b841045036c08dabd8c853142eef0dd623abf3f64412ccf\",\"dweb:/ipfs/QmVQHZP1H3xwGNa4NFa2R9U3BVUucw7N8jvRvqdD9KUp6U\"]}},\"version\":1}","userdoc":{"kind":"user","events":{"BorrowRateUpdate(bytes32,uint256,uint256)":{"notice":"Emitted when a borrow rate is updated."}},"methods":{"MORPHO()":{"notice":"Address of Morpho."},"constructor":{"notice":"Constructor."},"rateAtTarget(bytes32)":{"notice":"Rate at target utilization."},"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"notice":"Returns the borrow rate per second (scaled by WAD) of the market `marketParams`."},"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"notice":"Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any storage."}},"version":1},"devdoc":{"kind":"dev","title":"AdaptiveCurveIrm","author":"Morpho Labs","methods":{"constructor":{"params":{"morpho":"The address of Morpho."}},"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"details":"Assumes that `market` corresponds to `marketParams`."},"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))":{"details":"Assumes that `market` corresponds to `marketParams`."}},"version":1,"custom:contact":"security@morpho.org","stateVariables":{"rateAtTarget":{"details":"Tells the height of the curve."}}},"storageLayout":{"types":{"t_int256":{"label":"int256","encoding":"inplace","numberOfBytes":"32"},"t_userDefinedValueType(Id)34":{"label":"Id","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_userDefinedValueType(Id)34,t_int256)":{"key":"t_userDefinedValueType(Id)34","label":"mapping(Id => int256)","value":"t_int256","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_mapping(t_userDefinedValueType(Id)34,t_int256)","astId":665,"label":"rateAtTarget","offset":0,"contract":"src/AdaptiveCurveIrm.sol:AdaptiveCurveIrm"}]},"transientStorageLayout":null,"evm":{"bytecode":{"object":"60a03461011c57601f19610a3538819003601f810183168401936001600160401b03939092909183861085871117610106578084926040978852833960209384918101031261011c5751926001600160a01b03841680850361011c5785519182870190811183821017610106578652600c82526b7a65726f206164647265737360a01b84830152156100ad57505050608052516109139081610122823960805181818160bc015261026b0152f35b82855192839162461bcd60e51b835280600484015283519081602485015260005b8281106100ef5750506044935080600085601f938601015201168101030190fd5b8086018201518782016044015286945081016100ce565b634e487b7160e01b600052604160045260246000fd5b600080fdfe6080604090808252600436101561001557600080fd5b600090813560e01c90816301977b571461028f575080633acb5624146102205780638c00bf6b146101f457639451fed41461004f57600080fd5b346101f15761005d366102d6565b8351939184830167ffffffffffffffff8111868210176101c4578352600a85526020947f6e6f74204d6f7270686f000000000000000000000000000000000000000000008682015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036101315750828061011460a07f7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321942094856104ff565b91878684939952808a52205581519086825287820152a251908152f35b84908685519283917f08c379a0000000000000000000000000000000000000000000000000000000008352806004840152835193846024850152825b8581106101ad57505050601f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092604480968601015201168101030190fd5b81810183015187820160440152869450820161016d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b50903461021c5760209061021460a061020c366102d6565b9190206104ff565b509051908152f35b5080fd5b50903461021c57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021c576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b905082346102d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102d257602092600435815280845220548152f35b8280fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820161016081126104415760a013610441576040805167ffffffffffffffff919060a081018381118282101761044657825273ffffffffffffffffffffffffffffffffffffffff6004358181168103610441578252602435818116810361044157602083015260443581811681036104415783830152606435908116810361044157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c91606060c094015260843560808201529501126104415780519160c08301908111838210176104465781526fffffffffffffffffffffffffffffffff9060a435828116810361044157835260c435828116810361044157602084015260e435908282168203610441578301526101043581811681036104415760608301526101243581811681036104415760808301526101443590811681036104415760a082015290565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291600082127f80000000000000000000000000000000000000000000000000000000000000008214166104b45781840514901517156104b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919091600083820193841291129080158216911516176104b457565b81519092916fffffffffffffffffffffffffffffffff91821680156000816107c357508360408401511690670de0b6b3a7640000918281029281840414901517156104b45761078f5704915b670c7d713b49da0000808413156107be575067016345785d8a00005b7ffffffffffffffffffffffffffffffffffffffffffffffffff3828ec4b626000084019384136001166104b457670de0b6b3a764000093848102908082058614901517156104b457811561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f80000000000000000000000000000000000000000000000000000000000000008214166104b4570594600052600060205260406000205491600091831560001461067a5750505050634b9a1eff8161064482955b600081121561066c57670a688906bd8b0000610475565b059082820191600084841291129080158216911516176104b45761066791610475565b059190565b6729a2241af62c0000610475565b650171268b5ad49187830292830588036107625760800151164203904282116107355790846106a99205610475565b806106bb57505081610644829561062d565b906106e1826106db6106d1869560029a976107cc565b98899205856107cc565b936104e3565b908260011b926002840503610708575060046107018593610644936104e3565b059261062d565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b610567565b9150509161054b565b6107e8906107e2670de0b6b3a764000093610807565b90610475565b05640ec41a0ddf81811290821802186301e3da5f818113908218021890565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d881126108d7576805168fd0946fc0415f8112156108b95760008112156108aa577ffffffffffffffffffffffffffffffffffffffffffffffffffb30b927e6d498d2905b67099e8db03256ce5d80928201059182029003670de0b6b3a764000090600282828002050501019060008112156000146108a3571b90565b6000031d90565b6704cf46d8192b672e9061086b565b50780931d81650c7d88b800000000000000000000000000000000090565b5060009056fea2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","sourceMap":"852:6304:4:-:0;;;;-1:-1:-1;;852:6304:4;;;;;;;;;;;;;-1:-1:-1;;;;;852:6304:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;852:6304:4;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;852:6304:4;;;;1556:20;302:14:6;;1612:15:4;;;;;852:6304;;;;;;;1612:15;852:6304;;;;;;;;;;;302:14:6;852:6304:4;;;302:14:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;302:14:6;;;;;;;;;;;;-1:-1:-1;302:14:6;852:6304:4;302:14:6;;;;;852:6304:4;;302:14:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;302:14:6;;;;852:6304:4;;;;-1:-1:-1;852:6304:4;;;;;-1:-1:-1;852:6304:4;;-1:-1:-1;852:6304:4;","linkReferences":{}},"deployedBytecode":{"object":"6080604090808252600436101561001557600080fd5b600090813560e01c90816301977b571461028f575080633acb5624146102205780638c00bf6b146101f457639451fed41461004f57600080fd5b346101f15761005d366102d6565b8351939184830167ffffffffffffffff8111868210176101c4578352600a85526020947f6e6f74204d6f7270686f000000000000000000000000000000000000000000008682015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036101315750828061011460a07f7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321942094856104ff565b91878684939952808a52205581519086825287820152a251908152f35b84908685519283917f08c379a0000000000000000000000000000000000000000000000000000000008352806004840152835193846024850152825b8581106101ad57505050601f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092604480968601015201168101030190fd5b81810183015187820160440152869450820161016d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b50903461021c5760209061021460a061020c366102d6565b9190206104ff565b509051908152f35b5080fd5b50903461021c57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021c576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b905082346102d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102d257602092600435815280845220548152f35b8280fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820161016081126104415760a013610441576040805167ffffffffffffffff919060a081018381118282101761044657825273ffffffffffffffffffffffffffffffffffffffff6004358181168103610441578252602435818116810361044157602083015260443581811681036104415783830152606435908116810361044157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c91606060c094015260843560808201529501126104415780519160c08301908111838210176104465781526fffffffffffffffffffffffffffffffff9060a435828116810361044157835260c435828116810361044157602084015260e435908282168203610441578301526101043581811681036104415760608301526101243581811681036104415760808301526101443590811681036104415760a082015290565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291600082127f80000000000000000000000000000000000000000000000000000000000000008214166104b45781840514901517156104b457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919091600083820193841291129080158216911516176104b457565b81519092916fffffffffffffffffffffffffffffffff91821680156000816107c357508360408401511690670de0b6b3a7640000918281029281840414901517156104b45761078f5704915b670c7d713b49da0000808413156107be575067016345785d8a00005b7ffffffffffffffffffffffffffffffffffffffffffffffffff3828ec4b626000084019384136001166104b457670de0b6b3a764000093848102908082058614901517156104b457811561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82147f80000000000000000000000000000000000000000000000000000000000000008214166104b4570594600052600060205260406000205491600091831560001461067a5750505050634b9a1eff8161064482955b600081121561066c57670a688906bd8b0000610475565b059082820191600084841291129080158216911516176104b45761066791610475565b059190565b6729a2241af62c0000610475565b650171268b5ad49187830292830588036107625760800151164203904282116107355790846106a99205610475565b806106bb57505081610644829561062d565b906106e1826106db6106d1869560029a976107cc565b98899205856107cc565b936104e3565b908260011b926002840503610708575060046107018593610644936104e3565b059261062d565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b610567565b9150509161054b565b6107e8906107e2670de0b6b3a764000093610807565b90610475565b05640ec41a0ddf81811290821802186301e3da5f818113908218021890565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d881126108d7576805168fd0946fc0415f8112156108b95760008112156108aa577ffffffffffffffffffffffffffffffffffffffffffffffffffb30b927e6d498d2905b67099e8db03256ce5d80928201059182029003670de0b6b3a764000090600282828002050501019060008112156000146108a3571b90565b6000031d90565b6704cf46d8192b672e9061086b565b50780931d81650c7d88b800000000000000000000000000000000090565b5060009056fea2646970667358221220fe259a2ee87715626981f93ecd63c46bc3e883bf3ad413307213e2b98817832864736f6c63430008130033","sourceMap":"852:6304:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2067:6;852:6304;2053:10;:20;412:12:6;;696:118:2;;;2187:23:4;696:118:2;2334:55:4;696:118:2;;2187:23:4;;;:::i;:::-;852:6304;;;;;;;;;;;412:12:6;852:6304:4;;;;;;412:12:6;;;852:6304:4;2334:55;852:6304;;;;;412:12:6;852:6304:4;;;;;412:12:6;;;;;;;852:6304:4;412:12:6;;;;;;;;;;;;;;;;;;;;;852:6304:4;412:12:6;852:6304:4;412:12:6;;;;;;;;852:6304:4;;412:12:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;412:12:6;;;;852:6304:4;;;;;;;;;;;;;;;;;;;;;1832:38;696:118:2;852:6304:4;;;:::i;:::-;696:118:2;;;1832:38:4;:::i;:::-;852:6304;;;;;;;;;;;;;;;;;;;;;;;;;;;;1270:31;852:6304;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;852:6304:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;-1:-1:-1;852:6304:4;;;;-1:-1:-1;852:6304:4;;;;;-1:-1:-1;852:6304:4;606:27:9;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;153:11:7;606:27:9;153:11:7;;;;;606:27:9;153:11:7;606:27:9;;;;;;;;;;;;;;;;;;;;;;;;:::o;2545:3384:4:-;852:6304;;2545:3384;;;852:6304;;;;2776:28;;-1:-1:-1;2776:28:4;;;2807:24;;;;;852:6304;;93:4:3;;852:6304:4;;;;;;;;;;;;;;;;;;2776:94;;775:9:9;2905:45:4;;;775:9:9;;;2905:143:4;153:11:7;2905:143:4;153:11:7;;;;;;;;;;93:4:3;606:27:9;;;;;;;;;;;;;;;;153:11:7;;;;;;;;;;;;;;852:6304:4;-1:-1:-1;852:6304:4;-1:-1:-1;852:6304:4;;;-1:-1:-1;852:6304:4;153:11:7;3209:22:4;-1:-1:-1;3241:22:4;3278;;3274:2512;3278:22;;;3350:53;;;;153:11:7;3417:53:4;516:5:7;3417:53:4;3274:2512;;-1:-1:-1;6326:7:4;;-1:-1:-1;;;153:11:7;516:5;:::i;:::-;153:11;606:27:9;;;;;-1:-1:-1;606:27:9;;;;;;;;;;;;;;;;516:5:7;;;:::i;:::-;153:11;5859:63:4;2545:3384;:::o;6326:97::-;153:11:7;516:5;:::i;3274:2512:4:-;153:11:7;606:27:9;;;;;;;;;;;4005:17:4;;852:6304;;3987:15;606:27:9;3987:15:4;;606:27:9;;;;153:11:7;;4063:15:4;153:11:7;;4063:15:4;:::i;:::-;4097:21;;;4238:35;;;516:5:7;4238:35:4;4093:1683;3274:2512;;4093:1683;5509:53;5699:35;5509:53;5605:57;5509:53;;;5660:1;5509:53;;;:::i;:::-;153:11:7;;;;5605:57:4;;:::i;:::-;5699:35;;:::i;:::-;606:27:9;;153:11:7;606:27:9;;5660:1:4;606:27:9;;;;;5699:57:4;5760:1;5699:57;;;516:5:7;5699:57:4;;:::i;:::-;153:11:7;4093:1683:4;3274:2512;;606:27:9;153:11:7;;;;;;;;;606:27:9;153:11:7;;;;;;;;;606:27:9;153:11:7;;;;;;;;;;;-1:-1:-1;153:11:7;;;;;-1:-1:-1;153:11:7;2905:143:4;;;2776:94;;;;;;;6814:340;516:5:7;6814:340:4;7023:29;93:4:3;6814:340:4;7023:29;:::i;:::-;516:5:7;;:::i;:::-;153:11;;428:197:8;;;;;;;;153:11:7;428:197:8;;;;;;;;6814:340:4;:::o;941:1128:10:-;413:28;1112:14;;1108:28;;692:27;1238:21;;;1234:50;;1483:1;1479:5;;1483:1;;;318:26;1478:42;;318:26;;;;;;;;;;;93:4:3;318:26:10;1915:1;318:26;;;;;;;;1974:6;1483:1;1974:6;;;1970:82;1483:1;;;318:26;1982:25;:::o;1970:82::-;1483:1;318:26;;2026;:::o;1478:42::-;318:26;1478:42;;;1234:50;1261:23;822:66;1261:23;:::o;1108:28::-;1128:8;1135:1;1128:8;:::o","linkReferences":{},"immutableReferences":{"659":[{"start":188,"length":32},{"start":619,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"borrowRate((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))","signatureHash4":"0x9451fed4","signatureHash32":"0x9451fed4d1f30d9186f78cbdd52bb08e61b60d856f284ad83784cb06acb0754f"},{"signature":"borrowRateView((address,address,address,address,uint256),(uint128,uint128,uint128,uint128,uint128,uint128))","signatureHash4":"0x8c00bf6b","signatureHash32":"0x8c00bf6ba9f28eac57753f4c26d930190e427f0575a20e721486c4c9e7daf014"},{"signature":"MORPHO()","signatureHash4":"0x3acb5624","signatureHash32":"0x3acb56249d7cf21133c289cbed9c1eca23ca2e6f141cc3044cc435b69d0329c7"},{"signature":"rateAtTarget(bytes32)","signatureHash4":"0x01977b57","signatureHash32":"0x01977b57bb2192d5a9548bf5d88e5a8d84f7012effa71446398d584853235336"}],"event":[{"signature":"BorrowRateUpdate(bytes32,uint256,uint256)","signatureHash4":"0x7120161a","signatureHash32":"0x7120161a7b3d31251e01294ab351ef15a41b91659a36032e4641bb89b121e321"}],"error":[]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"exact_match","chainId":"8453","address":"0x46415998764C29aB2a25CbeA6254146D50D22687"}