From 941f7b7612e8862ebeeaa05c293f7d3630a3516a Mon Sep 17 00:00:00 2001 From: Skas Merkushin Date: Thu, 17 Apr 2025 18:12:41 +0200 Subject: [PATCH 01/13] feat: subgraph on base --- apps/local | 1 - bun.lockb | Bin 1285640 -> 1358680 bytes packages/subgraph/.gitignore | 34 ++++++ packages/subgraph/abis/Config.json | 1 + packages/subgraph/abis/Hub.json | 1 + packages/subgraph/abis/LoanToken.json | 1 + packages/subgraph/abis/SimpleLoan.json | 1 + .../abis/SimpleLoanSimpleProposal.json | 1 + packages/subgraph/package.json | 30 ++++++ packages/subgraph/project.json | 11 ++ packages/subgraph/schema.graphql | 97 ++++++++++++++++++ packages/subgraph/src/contract.ts | 37 +++++++ packages/subgraph/src/loan-mapping.ts | 84 +++++++++++++++ packages/subgraph/src/proposal-mapping.ts | 37 +++++++ packages/subgraph/subgraph.yaml | 30 ++++++ packages/subgraph/tests/.latest.json | 4 + packages/subgraph/tsconfig.json | 12 +++ packages/subgraph/tsconfig.lib.json | 28 +++++ packages/subgraph/tsconfig.spec.json | 34 ++++++ .../src/contracts/base-proposal-contract.ts | 1 - .../contracts/chain-link-proposal-contract.ts | 1 - .../contracts/elastic-proposal-contract.ts | 1 - packages/v1-sdk-react/package.json | 5 +- 23 files changed, 446 insertions(+), 6 deletions(-) delete mode 160000 apps/local create mode 100644 packages/subgraph/.gitignore create mode 100644 packages/subgraph/abis/Config.json create mode 100644 packages/subgraph/abis/Hub.json create mode 100644 packages/subgraph/abis/LoanToken.json create mode 100644 packages/subgraph/abis/SimpleLoan.json create mode 100644 packages/subgraph/abis/SimpleLoanSimpleProposal.json create mode 100644 packages/subgraph/package.json create mode 100644 packages/subgraph/project.json create mode 100644 packages/subgraph/schema.graphql create mode 100644 packages/subgraph/src/contract.ts create mode 100644 packages/subgraph/src/loan-mapping.ts create mode 100644 packages/subgraph/src/proposal-mapping.ts create mode 100644 packages/subgraph/subgraph.yaml create mode 100644 packages/subgraph/tests/.latest.json create mode 100644 packages/subgraph/tsconfig.json create mode 100644 packages/subgraph/tsconfig.lib.json create mode 100644 packages/subgraph/tsconfig.spec.json diff --git a/apps/local b/apps/local deleted file mode 160000 index a4b70ab8..00000000 --- a/apps/local +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a4b70ab823dc305df2fcf928d9155f923e13056f diff --git a/bun.lockb b/bun.lockb index 694adad72ef05291f9d6c8353ae5a3bf0dbe4a0f..92e00f6b4347afb62396ec7f6a063245d30fc340 100755 GIT binary patch delta 370349 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%0AZi^3FyaeC#~o*rthXcJq8(^+@k7Z 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

_(cJhWf{D6n)aW@~p`NPNy8y>er&sqHBHC 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 delta 325663 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�%zaaLe!CR=F<6?Xywi)2N}@=e<82 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�Wf2j@Kvi0^x=Sxo}ibajc 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%0Al#lHTsA>AXMT;k!=GlX*;75KS*V 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

4bY<(R_Gw2LQmGbu0-+x;>*>)pcay2&E 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

MJ~i8dMGm}I+PC>xkzbCUkIDOacT)$8 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 diff --git a/packages/subgraph/.gitignore b/packages/subgraph/.gitignore new file mode 100644 index 00000000..b542c60b --- /dev/null +++ b/packages/subgraph/.gitignore @@ -0,0 +1,34 @@ +# Graph CLI generated artifacts +build/ +generated/ + +# Dependency directories +node_modules/ +jspm_packages/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# dotenv environment variables file +.env + +# Testing +coverage +coverage.json + +# Typechain +typechain +typechain-types + +# Hardhat files +cache diff --git a/packages/subgraph/abis/Config.json b/packages/subgraph/abis/Config.json new file mode 100644 index 00000000..62459408 --- /dev/null +++ b/packages/subgraph/abis/Config.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"MAX_FEE","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"type":"function","name":"acceptOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"type":"function","name":"feeCollector","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getPoolAdapter","inputs":[{"name":"pool","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"contract IPoolAdapter"}],"stateMutability":"view"},{"type":"function","name":"getStateFingerprintComputer","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"contract IStateFingerpringComputer"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"_owner","type":"address","internalType":"address"},{"name":"_fee","type":"uint16","internalType":"uint16"},{"name":"_feeCollector","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"loanMetadataUri","inputs":[{"name":"loanContract","type":"address","internalType":"address"}],"outputs":[{"name":"uri","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"pendingOwner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"registerPoolAdapter","inputs":[{"name":"pool","type":"address","internalType":"address"},{"name":"adapter","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"registerStateFingerprintComputer","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"computer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setDefaultLOANMetadataUri","inputs":[{"name":"metadataUri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFee","inputs":[{"name":"_fee","type":"uint16","internalType":"uint16"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeCollector","inputs":[{"name":"_feeCollector","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setLOANMetadataUri","inputs":[{"name":"loanContract","type":"address","internalType":"address"},{"name":"metadataUri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"DefaultLOANMetadataUriUpdated","inputs":[{"name":"newUri","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"FeeCollectorUpdated","inputs":[{"name":"oldFeeCollector","type":"address","indexed":false,"internalType":"address"},{"name":"newFeeCollector","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"FeeUpdated","inputs":[{"name":"oldFee","type":"uint16","indexed":false,"internalType":"uint16"},{"name":"newFee","type":"uint16","indexed":false,"internalType":"uint16"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"LOANMetadataUriUpdated","inputs":[{"name":"loanContract","type":"address","indexed":true,"internalType":"address"},{"name":"newUri","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"InvalidComputerContract","inputs":[{"name":"computer","type":"address","internalType":"address"},{"name":"asset","type":"address","internalType":"address"}]},{"type":"error","name":"InvalidFeeValue","inputs":[{"name":"fee","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ZeroFeeCollector","inputs":[]},{"type":"error","name":"ZeroLoanContract","inputs":[]}],"bytecode":{"object":"0x608060405234801561001057600080fd5b50610019610028565b61002360006100e7565b610160565b600054610100900460ff16156100945760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b606580546001600160a01b031916905561010b8161010e602090811b6108eb17901c565b50565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610ec38061016f6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063a42dce80116100a2578063c4743ae011610071578063c4743ae01461026b578063cbf35d881461027e578063ddca3f4314610291578063e30c39781461029f578063f2fde38b146102b057600080fd5b8063a42dce80146101f7578063b20912311461020a578063bc063e1a14610236578063c415b95c1461025257600080fd5b8063715018a6116100e9578063715018a6146101b057806379ba5097146101b85780638da5cb5b146101c05780638e005553146101d1578063935bf0d7146101e457600080fd5b8063233557501461011b5780632df927ac146101445780634bbcf8de14610188578063708c0db91461019d575b600080fd5b61012e610129366004610ae1565b6102c3565b60405161013b9190610b03565b60405180910390f35b610170610152366004610ae1565b6001600160a01b039081166000908152609960205260409020541690565b6040516001600160a01b03909116815260200161013b565b61019b610196366004610bf4565b61042e565b005b61019b6101ab366004610c54565b6104c5565b61019b61063f565b61019b610653565b6033546001600160a01b0316610170565b61019b6101df366004610c97565b6106cd565b61019b6101f2366004610cb2565b6106de565b61019b610205366004610ae1565b6107bc565b610170610218366004610ae1565b6001600160a01b039081166000908152609a60205260409020541690565b61023f6103e881565b60405161ffff909116815260200161013b565b609754610170906201000090046001600160a01b031681565b61019b610279366004610ce5565b6107cd565b61019b61028c366004610cb2565b610844565b60975461023f9061ffff1681565b6065546001600160a01b0316610170565b61019b6102be366004610ae1565b61087a565b6001600160a01b03811660009081526098602052604090208054606091906102ea90610d22565b80601f016020809104026020016040519081016040528092919081815260200182805461031690610d22565b80156103635780601f1061033857610100808354040283529160200191610363565b820191906000526020600020905b81548152906001019060200180831161034657829003601f168201915b505050505090508051600003610429576000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e80546103a890610d22565b80601f01602080910402602001604051908101604052809291908181526020018280546103d490610d22565b80156104215780601f106103f657610100808354040283529160200191610421565b820191906000526020600020905b81548152906001019060200180831161040457829003601f168201915b505050505090505b919050565b61043661093d565b6001600160a01b03821661045d5760405163a9fcf0f560e01b815260040160405180910390fd5b6001600160a01b038216600090815260986020526040902061047f8282610dab565b50816001600160a01b03167f6004b71123e07b97df793497325c4438343da4eeb06cfe39475aa69d93476527826040516104b99190610b03565b60405180910390a25050565b600054610100900460ff16158080156104e55750600054600160ff909116105b806104ff5750303b1580156104ff575060005460ff166001145b6105675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801561058a576000805461ff0019166101001790555b6001600160a01b0384166105d85760405162461bcd60e51b81526020600482015260156024820152744f776e6572206973207a65726f206164647265737360581b604482015260640161055e565b6105e184610997565b6105ea826109b0565b6105f383610a45565b8015610639576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b61064761093d565b6106516000610997565b565b60655433906001600160a01b031681146106c15760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161055e565b6106ca81610997565b50565b6106d561093d565b6106ca81610a45565b6106e661093d565b6001600160a01b0381161561078e576040516261f76560e41b81526001600160a01b03838116600483015282169063061f765090602401602060405180830381865afa15801561073a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075e9190610e6b565b61078e5760405163e12aeae760e01b81526001600160a01b0380831660048301528316602482015260440161055e565b6001600160a01b03918216600090815260996020526040902080546001600160a01b03191691909216179055565b6107c461093d565b6106ca816109b0565b6107d561093d565b6000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e6108098282610dab565b507fe358eb330ebc40c9c9375742912f9c5a8ae1db2e9990a15039c889ba971e128b816040516108399190610b03565b60405180910390a150565b61084c61093d565b6001600160a01b039182166000908152609a6020526040902080546001600160a01b03191691909216179055565b61088261093d565b606580546001600160a01b0383166001600160a01b031990911681179091556108b36033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6033546001600160a01b031633146106515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055e565b606580546001600160a01b03191690556106ca816108eb565b6001600160a01b0381166109d757604051635fb3e86760e11b815260040160405180910390fd5b609780546001600160a01b038381166201000081810262010000600160b01b031985161790945560408051949093049091168084526020840191909152917f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f3891015b60405180910390a15050565b6103e861ffff82161115610a7a5760405163f6696bd560e01b815261ffff821660048201526103e8602482015260440161055e565b6097805461ffff83811661ffff1983168117909355604080519190921680825260208201939093527f2e7c4279000925b8ff0bca0e7109cbc47fc6f6c4edfb831ffe7466cf0af07fa09101610a39565b80356001600160a01b038116811461042957600080fd5b600060208284031215610af357600080fd5b610afc82610aca565b9392505050565b600060208083528351808285015260005b81811015610b3057858101830151858201604001528201610b14565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610b7857600080fd5b813567ffffffffffffffff80821115610b9357610b93610b51565b604051601f8301601f19908116603f01168101908282118183101715610bbb57610bbb610b51565b81604052838152866020858801011115610bd457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610c0757600080fd5b610c1083610aca565b9150602083013567ffffffffffffffff811115610c2c57600080fd5b610c3885828601610b67565b9150509250929050565b803561ffff8116811461042957600080fd5b600080600060608486031215610c6957600080fd5b610c7284610aca565b9250610c8060208501610c42565b9150610c8e60408501610aca565b90509250925092565b600060208284031215610ca957600080fd5b610afc82610c42565b60008060408385031215610cc557600080fd5b610cce83610aca565b9150610cdc60208401610aca565b90509250929050565b600060208284031215610cf757600080fd5b813567ffffffffffffffff811115610d0e57600080fd5b610d1a84828501610b67565b949350505050565b600181811c90821680610d3657607f821691505b602082108103610d5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610da657600081815260208120601f850160051c81016020861015610d835750805b601f850160051c820191505b81811015610da257828155600101610d8f565b5050505b505050565b815167ffffffffffffffff811115610dc557610dc5610b51565b610dd981610dd38454610d22565b84610d5c565b602080601f831160018114610e0e5760008415610df65750858301515b600019600386901b1c1916600185901b178555610da2565b600085815260208120601f198616915b82811015610e3d57888601518255948401946001909101908401610e1e565b5085821015610e5b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215610e7d57600080fd5b81518015158114610afc57600080fdfea264697066735822122050013480b7b3f1ae431e986d3a9984428851eaf65c04a2b9cba92ca8ac167a2164736f6c63430008100033","sourceMap":"497:8860:80:-:0;;;3563:205;;;;;;;;;-1:-1:-1;3699:22:80::1;:20;:22::i;:::-;3731:30;3758:1;3731:18;:30::i;:::-;497:8860:::0;;5939:280:27;6007:13;;;;;;;6006:14;5998:66;;;;-1:-1:-1;;;5998:66:27;;216:2:137;5998:66:27;;;198:21:137;255:2;235:18;;;228:30;294:34;274:18;;;267:62;-1:-1:-1;;;345:18:137;;;338:37;392:19;;5998:66:27;;;;;;;;6078:12;;6094:15;6078:12;;;:31;6074:139;;6125:12;:30;;-1:-1:-1;;6125:30:27;6140:15;6125:30;;;;;;6174:28;;564:36:137;;;6174:28:27;;552:2:137;537:18;6174:28:27;;;;;;;6074:139;5939:280::o;1798:153:25:-;1887:13;1880:20;;-1:-1:-1;;;;;;1880:20:25;;;1910:34;1935:8;1910:24;;;;;;;:34;;:::i;:::-;1798:153;:::o;2687:187:26:-;2779:6;;;-1:-1:-1;;;;;2795:17:26;;;-1:-1:-1;;;;;;2795:17:26;;;;;;;2827:40;;2779:6;;;2795:17;2779:6;;2827:40;;2760:16;;2827:40;2750:124;2687:187;:::o;422:184:137:-;497:8860:80;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063a42dce80116100a2578063c4743ae011610071578063c4743ae01461026b578063cbf35d881461027e578063ddca3f4314610291578063e30c39781461029f578063f2fde38b146102b057600080fd5b8063a42dce80146101f7578063b20912311461020a578063bc063e1a14610236578063c415b95c1461025257600080fd5b8063715018a6116100e9578063715018a6146101b057806379ba5097146101b85780638da5cb5b146101c05780638e005553146101d1578063935bf0d7146101e457600080fd5b8063233557501461011b5780632df927ac146101445780634bbcf8de14610188578063708c0db91461019d575b600080fd5b61012e610129366004610ae1565b6102c3565b60405161013b9190610b03565b60405180910390f35b610170610152366004610ae1565b6001600160a01b039081166000908152609960205260409020541690565b6040516001600160a01b03909116815260200161013b565b61019b610196366004610bf4565b61042e565b005b61019b6101ab366004610c54565b6104c5565b61019b61063f565b61019b610653565b6033546001600160a01b0316610170565b61019b6101df366004610c97565b6106cd565b61019b6101f2366004610cb2565b6106de565b61019b610205366004610ae1565b6107bc565b610170610218366004610ae1565b6001600160a01b039081166000908152609a60205260409020541690565b61023f6103e881565b60405161ffff909116815260200161013b565b609754610170906201000090046001600160a01b031681565b61019b610279366004610ce5565b6107cd565b61019b61028c366004610cb2565b610844565b60975461023f9061ffff1681565b6065546001600160a01b0316610170565b61019b6102be366004610ae1565b61087a565b6001600160a01b03811660009081526098602052604090208054606091906102ea90610d22565b80601f016020809104026020016040519081016040528092919081815260200182805461031690610d22565b80156103635780601f1061033857610100808354040283529160200191610363565b820191906000526020600020905b81548152906001019060200180831161034657829003601f168201915b505050505090508051600003610429576000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e80546103a890610d22565b80601f01602080910402602001604051908101604052809291908181526020018280546103d490610d22565b80156104215780601f106103f657610100808354040283529160200191610421565b820191906000526020600020905b81548152906001019060200180831161040457829003601f168201915b505050505090505b919050565b61043661093d565b6001600160a01b03821661045d5760405163a9fcf0f560e01b815260040160405180910390fd5b6001600160a01b038216600090815260986020526040902061047f8282610dab565b50816001600160a01b03167f6004b71123e07b97df793497325c4438343da4eeb06cfe39475aa69d93476527826040516104b99190610b03565b60405180910390a25050565b600054610100900460ff16158080156104e55750600054600160ff909116105b806104ff5750303b1580156104ff575060005460ff166001145b6105675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801561058a576000805461ff0019166101001790555b6001600160a01b0384166105d85760405162461bcd60e51b81526020600482015260156024820152744f776e6572206973207a65726f206164647265737360581b604482015260640161055e565b6105e184610997565b6105ea826109b0565b6105f383610a45565b8015610639576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b61064761093d565b6106516000610997565b565b60655433906001600160a01b031681146106c15760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161055e565b6106ca81610997565b50565b6106d561093d565b6106ca81610a45565b6106e661093d565b6001600160a01b0381161561078e576040516261f76560e41b81526001600160a01b03838116600483015282169063061f765090602401602060405180830381865afa15801561073a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075e9190610e6b565b61078e5760405163e12aeae760e01b81526001600160a01b0380831660048301528316602482015260440161055e565b6001600160a01b03918216600090815260996020526040902080546001600160a01b03191691909216179055565b6107c461093d565b6106ca816109b0565b6107d561093d565b6000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e6108098282610dab565b507fe358eb330ebc40c9c9375742912f9c5a8ae1db2e9990a15039c889ba971e128b816040516108399190610b03565b60405180910390a150565b61084c61093d565b6001600160a01b039182166000908152609a6020526040902080546001600160a01b03191691909216179055565b61088261093d565b606580546001600160a01b0383166001600160a01b031990911681179091556108b36033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6033546001600160a01b031633146106515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055e565b606580546001600160a01b03191690556106ca816108eb565b6001600160a01b0381166109d757604051635fb3e86760e11b815260040160405180910390fd5b609780546001600160a01b038381166201000081810262010000600160b01b031985161790945560408051949093049091168084526020840191909152917f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f3891015b60405180910390a15050565b6103e861ffff82161115610a7a5760405163f6696bd560e01b815261ffff821660048201526103e8602482015260440161055e565b6097805461ffff83811661ffff1983168117909355604080519190921680825260208201939093527f2e7c4279000925b8ff0bca0e7109cbc47fc6f6c4edfb831ffe7466cf0af07fa09101610a39565b80356001600160a01b038116811461042957600080fd5b600060208284031215610af357600080fd5b610afc82610aca565b9392505050565b600060208083528351808285015260005b81811015610b3057858101830151858201604001528201610b14565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610b7857600080fd5b813567ffffffffffffffff80821115610b9357610b93610b51565b604051601f8301601f19908116603f01168101908282118183101715610bbb57610bbb610b51565b81604052838152866020858801011115610bd457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610c0757600080fd5b610c1083610aca565b9150602083013567ffffffffffffffff811115610c2c57600080fd5b610c3885828601610b67565b9150509250929050565b803561ffff8116811461042957600080fd5b600080600060608486031215610c6957600080fd5b610c7284610aca565b9250610c8060208501610c42565b9150610c8e60408501610aca565b90509250925092565b600060208284031215610ca957600080fd5b610afc82610c42565b60008060408385031215610cc557600080fd5b610cce83610aca565b9150610cdc60208401610aca565b90509250929050565b600060208284031215610cf757600080fd5b813567ffffffffffffffff811115610d0e57600080fd5b610d1a84828501610b67565b949350505050565b600181811c90821680610d3657607f821691505b602082108103610d5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610da657600081815260208120601f850160051c81016020861015610d835750805b601f850160051c820191505b81811015610da257828155600101610d8f565b5050505b505050565b815167ffffffffffffffff811115610dc557610dc5610b51565b610dd981610dd38454610d22565b84610d5c565b602080601f831160018114610e0e5760008415610df65750858301515b600019600386901b1c1916600185901b178555610da2565b600085815260208120601f198616915b82811015610e3d57888601518255948401946001909101908401610e1e565b5085821015610e5b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215610e7d57600080fd5b81518015158114610afc57600080fdfea264697066735822122050013480b7b3f1ae431e986d3a9984428851eaf65c04a2b9cba92ca8ac167a2164736f6c63430008100033","sourceMap":"497:8860:80:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6987:312;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7713:179;;;;;;:::i;:::-;-1:-1:-1;;;;;7858:26:80;;;7788:25;7858:26;;;:19;:26;;;;;;;;7713:179;;;;-1:-1:-1;;;;;1135:32:137;;;1117:51;;1105:2;1090:18;7713:179:80;936:238:137;5990:423:80;;;;;;:::i;:::-;;:::i;:::-;;3774:264;;;;;;:::i;:::-;;:::i;2085:101:26:-;;;:::i;2031:212:25:-;;;:::i;1462:85:26:-;1534:6;;-1:-1:-1;;;;;1534:6:26;1462:85;;4380:78:80;;;;;;:::i;:::-;;:::i;8146:346::-;;;;;;:::i;:::-;;:::i;4980:115::-;;;;;;:::i;:::-;;:::i;8886:139::-;;;;;;:::i;:::-;-1:-1:-1;;;;;8991:26:80;;;8947:12;8991:26;;;:20;:26;;;;;;;;8886:139;799:37;;832:4;799:37;;;;;4003:6:137;3991:19;;;3973:38;;3961:2;3946:18;799:37:80;3829:188:137;1045:27:80;;;;;;;;-1:-1:-1;;;;;1045:27:80;;;6561:197;;;;;;:::i;:::-;;:::i;9222:132::-;;;;;;:::i;:::-;;:::i;953:17::-;;;;;;;;;1144:99:25;1223:13;;-1:-1:-1;;;;;1223:13:25;1144:99;;1436:178;;;;;;:::i;:::-;;:::i;6987:312:80:-;-1:-1:-1;;;;;7092:30:80;;;;;;:16;:30;;;;;7086:36;;7057:17;;7092:30;7086:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7228:3;7222:17;7243:1;7222:22;7218:74;;7264:28;;;:16;:28;;;7258:34;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7218:74;6987:312;;;:::o;5990:423::-;1355:13:26;:11;:13::i;:::-;-1:-1:-1;;;;;6100:26:80;::::1;6096:191;;6269:18;;-1:-1:-1::0;;;6269:18:80::1;;;;;;;;;;;6096:191;-1:-1:-1::0;;;;;6298:30:80;::::1;;::::0;;;:16:::1;:30;::::0;;;;:44:::1;6331:11:::0;6298:30;:44:::1;:::i;:::-;;6380:12;-1:-1:-1::0;;;;;6357:49:80::1;;6394:11;6357:49;;;;;;:::i;:::-;;;;;;;;5990:423:::0;;:::o;3774:264::-;3279:19:27;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:27;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:27;1713:19:28;:23;;;3387:66:27;;-1:-1:-1;3436:12:27;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:27;;7140:2:137;3325:201:27;;;7122:21:137;7179:2;7159:18;;;7152:30;7218:34;7198:18;;;7191:62;-1:-1:-1;;;7269:18:137;;;7262:44;7323:19;;3325:201:27;;;;;;;;;3536:12;:16;;-1:-1:-1;;3536:16:27;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;-1:-1:-1;;3596:20:27;;;;;3562:65;-1:-1:-1;;;;;3885:20:80;::::1;3877:54;;;::::0;-1:-1:-1;;;3877:54:80;;7555:2:137;3877:54:80::1;::::0;::::1;7537:21:137::0;7594:2;7574:18;;;7567:30;-1:-1:-1;;;7613:18:137;;;7606:51;7674:18;;3877:54:80::1;7353:345:137::0;3877:54:80::1;3941:26;3960:6;3941:18;:26::i;:::-;3977:31;3994:13;3977:16;:31::i;:::-;4018:13;4026:4;4018:7;:13::i;:::-;3651:14:27::0;3647:99;;;3697:5;3681:21;;-1:-1:-1;;3681:21:27;;;3721:14;;-1:-1:-1;7855:36:137;;3721:14:27;;7843:2:137;7828:18;3721:14:27;;;;;;;3647:99;3269:483;3774:264:80;;;:::o;2085:101:26:-;1355:13;:11;:13::i;:::-;2149:30:::1;2176:1;2149:18;:30::i;:::-;2085:101::o:0;2031:212:25:-;1223:13;;965:10:29;;-1:-1:-1;;;;;1223:13:25;2130:24;;2122:78;;;;-1:-1:-1;;;2122:78:25;;8104:2:137;2122:78:25;;;8086:21:137;8143:2;8123:18;;;8116:30;8182:34;8162:18;;;8155:62;-1:-1:-1;;;8233:18:137;;;8226:39;8282:19;;2122:78:25;7902:405:137;2122:78:25;2210:26;2229:6;2210:18;:26::i;:::-;2073:170;2031:212::o;4380:78:80:-;1355:13:26;:11;:13::i;:::-;4438::80::1;4446:4;4438:7;:13::i;8146:346::-:0;1355:13:26;:11;:13::i;:::-;-1:-1:-1;;;;;8254:22:80;::::1;::::0;8250:187:::1;;8295:56;::::0;-1:-1:-1;;;8295:56:80;;-1:-1:-1;;;;;1135:32:137;;;8295:56:80::1;::::0;::::1;1117:51:137::0;8295:49:80;::::1;::::0;::::1;::::0;1090:18:137;;8295:56:80::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8290:147;;8376:61;::::0;-1:-1:-1;;;8376:61:80;;-1:-1:-1;;;;;8824:15:137;;;8376:61:80::1;::::0;::::1;8806:34:137::0;8876:15;;8856:18;;;8849:43;8741:18;;8376:61:80::1;8594:304:137::0;8290:147:80::1;-1:-1:-1::0;;;;;8448:26:80;;::::1;;::::0;;;:19:::1;:26;::::0;;;;:37;;-1:-1:-1;;;;;;8448:37:80::1;::::0;;;::::1;;::::0;;8146:346::o;4980:115::-;1355:13:26;:11;:13::i;:::-;5057:31:80::1;5074:13;5057:16;:31::i;6561:197::-:0;1355:13:26;:11;:13::i;:::-;6652:28:80::1;::::0;;:16:::1;:28;::::0;;:42:::1;6683:11:::0;6652:28;:42:::1;:::i;:::-;;6709;6739:11;6709:42;;;;;;:::i;:::-;;;;;;;;6561:197:::0;:::o;9222:132::-;1355:13:26;:11;:13::i;:::-;-1:-1:-1;;;;;9311:26:80;;::::1;;::::0;;;:20:::1;:26;::::0;;;;:36;;-1:-1:-1;;;;;;9311:36:80::1;::::0;;;::::1;;::::0;;9222:132::o;1436:178:25:-;1355:13:26;:11;:13::i;:::-;1525::25::1;:24:::0;;-1:-1:-1;;;;;1525:24:25;::::1;-1:-1:-1::0;;;;;;1525:24:25;;::::1;::::0;::::1;::::0;;;1589:7:::1;1534:6:26::0;;-1:-1:-1;;;;;1534:6:26;;1462:85;1589:7:25::1;-1:-1:-1::0;;;;;1564:43:25::1;;;;;;;;;;;1436:178:::0;:::o;2687:187:26:-;2779:6;;;-1:-1:-1;;;;;2795:17:26;;;-1:-1:-1;;;;;;2795:17:26;;;;;;;2827:40;;2779:6;;;2795:17;2779:6;;2827:40;;2760:16;;2827:40;2750:124;2687:187;:::o;1620:130::-;1534:6;;-1:-1:-1;;;;;1534:6:26;965:10:29;1683:23:26;1675:68;;;;-1:-1:-1;;;1675:68:26;;9105:2:137;1675:68:26;;;9087:21:137;;;9124:18;;;9117:30;9183:34;9163:18;;;9156:62;9235:18;;1675:68:26;8903:356:137;1798:153:25;1887:13;1880:20;;-1:-1:-1;;;;;;1880:20:25;;;1910:34;1935:8;1910:24;:34::i;5249:297:80:-;-1:-1:-1;;;;;5320:27:80;;5316:70;;5368:18;;-1:-1:-1;;;5368:18:80;;;;;;;;;;;5316:70;5423:12;;;-1:-1:-1;;;;;5445:28:80;;;5423:12;5445:28;;;-1:-1:-1;;;;;;5445:28:80;;;;;;5488:51;;;5423:12;;;;;;;8806:34:137;;;8871:2;8856:18;;8849:43;;;;5423:12:80;5488:51;;8741:18:137;5488:51:80;;;;;;;;5306:240;5249:297;:::o;4628:229::-;832:4;4680:14;;;;4676:85;;;4715:46;;-1:-1:-1;;;4715:46:80;;9446:6:137;9479:15;;4715:46:80;;;9461:34:137;832:4:80;9511:18:137;;;9504:43;9409:18;;4715:46:80;9264:289:137;4676:85:80;4788:3;;;;4801:10;;;-1:-1:-1;;4801:10:80;;;;;;;4826:24;;;4788:3;;;;9461:34:137;;;9526:2;9511:18;;9504:43;;;;4826:24:80;;9409:18:137;4826:24:80;9264:289:137;14:173;82:20;;-1:-1:-1;;;;;131:31:137;;121:42;;111:70;;177:1;174;167:12;192:186;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;:::-;333:39;192:186;-1:-1:-1;;;192:186:137:o;383:548::-;495:4;524:2;553;542:9;535:21;585:6;579:13;628:6;623:2;612:9;608:18;601:34;653:1;663:140;677:6;674:1;671:13;663:140;;;772:14;;;768:23;;762:30;738:17;;;757:2;734:26;727:66;692:10;;663:140;;;667:3;852:1;847:2;838:6;827:9;823:22;819:31;812:42;922:2;915;911:7;906:2;898:6;894:15;890:29;879:9;875:45;871:54;863:62;;;;383:548;;;;:::o;1179:127::-;1240:10;1235:3;1231:20;1228:1;1221:31;1271:4;1268:1;1261:15;1295:4;1292:1;1285:15;1311:719;1354:5;1407:3;1400:4;1392:6;1388:17;1384:27;1374:55;;1425:1;1422;1415:12;1374:55;1461:6;1448:20;1487:18;1524:2;1520;1517:10;1514:36;;;1530:18;;:::i;:::-;1605:2;1599:9;1573:2;1659:13;;-1:-1:-1;;1655:22:137;;;1679:2;1651:31;1647:40;1635:53;;;1703:18;;;1723:22;;;1700:46;1697:72;;;1749:18;;:::i;:::-;1789:10;1785:2;1778:22;1824:2;1816:6;1809:18;1870:3;1863:4;1858:2;1850:6;1846:15;1842:26;1839:35;1836:55;;;1887:1;1884;1877:12;1836:55;1951:2;1944:4;1936:6;1932:17;1925:4;1917:6;1913:17;1900:54;1998:1;1991:4;1986:2;1978:6;1974:15;1970:26;1963:37;2018:6;2009:15;;;;;;1311:719;;;;:::o;2035:396::-;2113:6;2121;2174:2;2162:9;2153:7;2149:23;2145:32;2142:52;;;2190:1;2187;2180:12;2142:52;2213:29;2232:9;2213:29;:::i;:::-;2203:39;;2293:2;2282:9;2278:18;2265:32;2320:18;2312:6;2309:30;2306:50;;;2352:1;2349;2342:12;2306:50;2375;2417:7;2408:6;2397:9;2393:22;2375:50;:::i;:::-;2365:60;;;2035:396;;;;;:::o;2436:159::-;2503:20;;2563:6;2552:18;;2542:29;;2532:57;;2585:1;2582;2575:12;2600:332;2676:6;2684;2692;2745:2;2733:9;2724:7;2720:23;2716:32;2713:52;;;2761:1;2758;2751:12;2713:52;2784:29;2803:9;2784:29;:::i;:::-;2774:39;;2832:37;2865:2;2854:9;2850:18;2832:37;:::i;:::-;2822:47;;2888:38;2922:2;2911:9;2907:18;2888:38;:::i;:::-;2878:48;;2600:332;;;;;:::o;3145:184::-;3203:6;3256:2;3244:9;3235:7;3231:23;3227:32;3224:52;;;3272:1;3269;3262:12;3224:52;3295:28;3313:9;3295:28;:::i;3334:260::-;3402:6;3410;3463:2;3451:9;3442:7;3438:23;3434:32;3431:52;;;3479:1;3476;3469:12;3431:52;3502:29;3521:9;3502:29;:::i;:::-;3492:39;;3550:38;3584:2;3573:9;3569:18;3550:38;:::i;:::-;3540:48;;3334:260;;;;;:::o;4022:322::-;4091:6;4144:2;4132:9;4123:7;4119:23;4115:32;4112:52;;;4160:1;4157;4150:12;4112:52;4200:9;4187:23;4233:18;4225:6;4222:30;4219:50;;;4265:1;4262;4255:12;4219:50;4288;4330:7;4321:6;4310:9;4306:22;4288:50;:::i;:::-;4278:60;4022:322;-1:-1:-1;;;;4022:322:137:o;4349:380::-;4428:1;4424:12;;;;4471;;;4492:61;;4546:4;4538:6;4534:17;4524:27;;4492:61;4599:2;4591:6;4588:14;4568:18;4565:38;4562:161;;4645:10;4640:3;4636:20;4633:1;4626:31;4680:4;4677:1;4670:15;4708:4;4705:1;4698:15;4562:161;;4349:380;;;:::o;4860:545::-;4962:2;4957:3;4954:11;4951:448;;;4998:1;5023:5;5019:2;5012:17;5068:4;5064:2;5054:19;5138:2;5126:10;5122:19;5119:1;5115:27;5109:4;5105:38;5174:4;5162:10;5159:20;5156:47;;;-1:-1:-1;5197:4:137;5156:47;5252:2;5247:3;5243:12;5240:1;5236:20;5230:4;5226:31;5216:41;;5307:82;5325:2;5318:5;5315:13;5307:82;;;5370:17;;;5351:1;5340:13;5307:82;;;5311:3;;;4951:448;4860:545;;;:::o;5581:1352::-;5707:3;5701:10;5734:18;5726:6;5723:30;5720:56;;;5756:18;;:::i;:::-;5785:97;5875:6;5835:38;5867:4;5861:11;5835:38;:::i;:::-;5829:4;5785:97;:::i;:::-;5937:4;;6001:2;5990:14;;6018:1;6013:663;;;;6720:1;6737:6;6734:89;;;-1:-1:-1;6789:19:137;;;6783:26;6734:89;-1:-1:-1;;5538:1:137;5534:11;;;5530:24;5526:29;5516:40;5562:1;5558:11;;;5513:57;6836:81;;5983:944;;6013:663;4807:1;4800:14;;;4844:4;4831:18;;-1:-1:-1;;6049:20:137;;;6167:236;6181:7;6178:1;6175:14;6167:236;;;6270:19;;;6264:26;6249:42;;6362:27;;;;6330:1;6318:14;;;;6197:19;;6167:236;;;6171:3;6431:6;6422:7;6419:19;6416:201;;;6492:19;;;6486:26;-1:-1:-1;;6575:1:137;6571:14;;;6587:3;6567:24;6563:37;6559:42;6544:58;6529:74;;6416:201;-1:-1:-1;;;;;6663:1:137;6647:14;;;6643:22;6630:36;;-1:-1:-1;5581:1352:137:o;8312:277::-;8379:6;8432:2;8420:9;8411:7;8407:23;8403:32;8400:52;;;8448:1;8445;8438:12;8400:52;8480:9;8474:16;8533:5;8526:13;8519:21;8512:5;8509:32;8499:60;;8555:1;8552;8545:12","linkReferences":{}},"methodIdentifiers":{"MAX_FEE()":"bc063e1a","acceptOwnership()":"79ba5097","fee()":"ddca3f43","feeCollector()":"c415b95c","getPoolAdapter(address)":"b2091231","getStateFingerprintComputer(address)":"2df927ac","initialize(address,uint16,address)":"708c0db9","loanMetadataUri(address)":"23355750","owner()":"8da5cb5b","pendingOwner()":"e30c3978","registerPoolAdapter(address,address)":"cbf35d88","registerStateFingerprintComputer(address,address)":"935bf0d7","renounceOwnership()":"715018a6","setDefaultLOANMetadataUri(string)":"c4743ae0","setFee(uint16)":"8e005553","setFeeCollector(address)":"a42dce80","setLOANMetadataUri(address,string)":"4bbcf8de","transferOwnership(address)":"f2fde38b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"computer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"InvalidComputerContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InvalidFeeValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroFeeCollector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroLoanContract\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newUri\",\"type\":\"string\"}],\"name\":\"DefaultLOANMetadataUriUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeCollector\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeCollector\",\"type\":\"address\"}],\"name\":\"FeeCollectorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"oldFee\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"newFee\",\"type\":\"uint16\"}],\"name\":\"FeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newUri\",\"type\":\"string\"}],\"name\":\"LOANMetadataUriUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_FEE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeCollector\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"getPoolAdapter\",\"outputs\":[{\"internalType\":\"contract IPoolAdapter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getStateFingerprintComputer\",\"outputs\":[{\"internalType\":\"contract IStateFingerpringComputer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"_fee\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"_feeCollector\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"name\":\"loanMetadataUri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"uri\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"adapter\",\"type\":\"address\"}],\"name\":\"registerPoolAdapter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"computer\",\"type\":\"address\"}],\"name\":\"registerStateFingerprintComputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"metadataUri\",\"type\":\"string\"}],\"name\":\"setDefaultLOANMetadataUri\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_fee\",\"type\":\"uint16\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_feeCollector\",\"type\":\"address\"}],\"name\":\"setFeeCollector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"metadataUri\",\"type\":\"string\"}],\"name\":\"setLOANMetadataUri\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Is intended to be used as a proxy via `TransparentUpgradeableProxy`.\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"getPoolAdapter(address)\":{\"params\":{\"pool\":\"The pool for which the adapter is requested.\"},\"returns\":{\"_0\":\"The adapter for the given pool.\"}},\"getStateFingerprintComputer(address)\":{\"params\":{\"asset\":\"The asset for which the computer is requested.\"},\"returns\":{\"_0\":\"The computer for the given asset.\"}},\"loanMetadataUri(address)\":{\"params\":{\"loanContract\":\"Address of a loan contract.\"},\"returns\":{\"uri\":\"Metadata uri for given loan contract.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"registerPoolAdapter(address,address)\":{\"params\":{\"adapter\":\"The adapter to be registered.\",\"pool\":\"The pool for which the adapter is registered.\"}},\"registerStateFingerprintComputer(address,address)\":{\"params\":{\"asset\":\"The asset for which the computer is registered.\",\"computer\":\"The computer to be registered. Use address(0) to remove a computer.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setDefaultLOANMetadataUri(string)\":{\"params\":{\"metadataUri\":\"New value of default LOAN token metadata uri.\"}},\"setFee(uint16)\":{\"params\":{\"_fee\":\"New fee value in basis points. Value of 100 is 1% fee.\"}},\"setFeeCollector(address)\":{\"params\":{\"_feeCollector\":\"New fee collector address.\"}},\"setLOANMetadataUri(address,string)\":{\"params\":{\"loanContract\":\"Address of a loan contract.\",\"metadataUri\":\"New value of LOAN token metadata uri for given `loanContract`.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"stateVariables\":{\"_loanMetadataUri\":{\"details\":\"LOAN token minted by a loan contract will return metadata uri stored in this mapping. If there is no metadata uri for a loan contract, default metadata uri will be used stored under address(0).\"},\"fee\":{\"details\":\"Value of 100 is 1% fee.\"}},\"title\":\"PWN Config\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidComputerContract(address,address)\":[{\"notice\":\"Thrown when registering a computer which does not support the asset it is registered for.\"}],\"InvalidFeeValue(uint256,uint256)\":[{\"notice\":\"Thrown when trying to set a fee value higher than `MAX_FEE`.\"}],\"ZeroFeeCollector()\":[{\"notice\":\"Thrown when trying to set a fee collector to zero address.\"}],\"ZeroLoanContract()\":[{\"notice\":\"Thrown when trying to set a LOAN token metadata uri for zero address loan contract.\"}]},\"events\":{\"DefaultLOANMetadataUriUpdated(string)\":{\"notice\":\"Emitted when new default LOAN token metadata uri is set.\"},\"FeeCollectorUpdated(address,address)\":{\"notice\":\"Emitted when new fee collector address is set.\"},\"FeeUpdated(uint16,uint16)\":{\"notice\":\"Emitted when new fee value is set.\"},\"LOANMetadataUriUpdated(address,string)\":{\"notice\":\"Emitted when new LOAN token metadata uri is set.\"}},\"kind\":\"user\",\"methods\":{\"fee()\":{\"notice\":\"Protocol fee value in basis points.\"},\"feeCollector()\":{\"notice\":\"Address that collects protocol fees.\"},\"getPoolAdapter(address)\":{\"notice\":\"Returns the pool adapter for a given pool.\"},\"getStateFingerprintComputer(address)\":{\"notice\":\"Returns the state fingerprint computer for a given asset.\"},\"loanMetadataUri(address)\":{\"notice\":\"Return a LOAN token metadata uri base on a loan contract that minted the token.\"},\"registerPoolAdapter(address,address)\":{\"notice\":\"Registers a pool adapter for a given pool.\"},\"registerStateFingerprintComputer(address,address)\":{\"notice\":\"Registers a state fingerprint computer for a given asset.\"},\"setDefaultLOANMetadataUri(string)\":{\"notice\":\"Set a default LOAN token metadata uri.\"},\"setFee(uint16)\":{\"notice\":\"Set new protocol fee value.\"},\"setFeeCollector(address)\":{\"notice\":\"Set new fee collector address.\"},\"setLOANMetadataUri(address,string)\":{\"notice\":\"Set a LOAN token metadata uri for a specific loan contract.\"}},\"notice\":\"Contract holding configurable values of PWN protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/config/PWNConfig.sol\":\"PWNConfig\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\":{\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16\",\"dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c\",\"dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e\",\"dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b\",\"dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95\",\"dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx\"]},\"src/config/PWNConfig.sol\":{\"keccak256\":\"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7\",\"dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz\"]},\"src/interfaces/IPoolAdapter.sol\":{\"keccak256\":\"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b\",\"dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T\"]},\"src/interfaces/IStateFingerpringComputer.sol\":{\"keccak256\":\"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c\",\"dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"computer","type":"address"},{"internalType":"address","name":"asset","type":"address"}],"type":"error","name":"InvalidComputerContract"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InvalidFeeValue"},{"inputs":[],"type":"error","name":"ZeroFeeCollector"},{"inputs":[],"type":"error","name":"ZeroLoanContract"},{"inputs":[{"internalType":"string","name":"newUri","type":"string","indexed":false}],"type":"event","name":"DefaultLOANMetadataUriUpdated","anonymous":false},{"inputs":[{"internalType":"address","name":"oldFeeCollector","type":"address","indexed":false},{"internalType":"address","name":"newFeeCollector","type":"address","indexed":false}],"type":"event","name":"FeeCollectorUpdated","anonymous":false},{"inputs":[{"internalType":"uint16","name":"oldFee","type":"uint16","indexed":false},{"internalType":"uint16","name":"newFee","type":"uint16","indexed":false}],"type":"event","name":"FeeUpdated","anonymous":false},{"inputs":[{"internalType":"uint8","name":"version","type":"uint8","indexed":false}],"type":"event","name":"Initialized","anonymous":false},{"inputs":[{"internalType":"address","name":"loanContract","type":"address","indexed":true},{"internalType":"string","name":"newUri","type":"string","indexed":false}],"type":"event","name":"LOANMetadataUriUpdated","anonymous":false},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferStarted","anonymous":false},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferred","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"MAX_FEE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"acceptOwnership"},{"inputs":[],"stateMutability":"view","type":"function","name":"fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"view","type":"function","name":"getPoolAdapter","outputs":[{"internalType":"contract IPoolAdapter","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"stateMutability":"view","type":"function","name":"getStateFingerprintComputer","outputs":[{"internalType":"contract IStateFingerpringComputer","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint16","name":"_fee","type":"uint16"},{"internalType":"address","name":"_feeCollector","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"initialize"},{"inputs":[{"internalType":"address","name":"loanContract","type":"address"}],"stateMutability":"view","type":"function","name":"loanMetadataUri","outputs":[{"internalType":"string","name":"uri","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"adapter","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"registerPoolAdapter"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"computer","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"registerStateFingerprintComputer"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"renounceOwnership"},{"inputs":[{"internalType":"string","name":"metadataUri","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"setDefaultLOANMetadataUri"},{"inputs":[{"internalType":"uint16","name":"_fee","type":"uint16"}],"stateMutability":"nonpayable","type":"function","name":"setFee"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"setFeeCollector"},{"inputs":[{"internalType":"address","name":"loanContract","type":"address"},{"internalType":"string","name":"metadataUri","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"setLOANMetadataUri"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"transferOwnership"}],"devdoc":{"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"getPoolAdapter(address)":{"params":{"pool":"The pool for which the adapter is requested."},"returns":{"_0":"The adapter for the given pool."}},"getStateFingerprintComputer(address)":{"params":{"asset":"The asset for which the computer is requested."},"returns":{"_0":"The computer for the given asset."}},"loanMetadataUri(address)":{"params":{"loanContract":"Address of a loan contract."},"returns":{"uri":"Metadata uri for given loan contract."}},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"registerPoolAdapter(address,address)":{"params":{"adapter":"The adapter to be registered.","pool":"The pool for which the adapter is registered."}},"registerStateFingerprintComputer(address,address)":{"params":{"asset":"The asset for which the computer is registered.","computer":"The computer to be registered. Use address(0) to remove a computer."}},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."},"setDefaultLOANMetadataUri(string)":{"params":{"metadataUri":"New value of default LOAN token metadata uri."}},"setFee(uint16)":{"params":{"_fee":"New fee value in basis points. Value of 100 is 1% fee."}},"setFeeCollector(address)":{"params":{"_feeCollector":"New fee collector address."}},"setLOANMetadataUri(address,string)":{"params":{"loanContract":"Address of a loan contract.","metadataUri":"New value of LOAN token metadata uri for given `loanContract`."}},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner."}},"version":1},"userdoc":{"kind":"user","methods":{"fee()":{"notice":"Protocol fee value in basis points."},"feeCollector()":{"notice":"Address that collects protocol fees."},"getPoolAdapter(address)":{"notice":"Returns the pool adapter for a given pool."},"getStateFingerprintComputer(address)":{"notice":"Returns the state fingerprint computer for a given asset."},"loanMetadataUri(address)":{"notice":"Return a LOAN token metadata uri base on a loan contract that minted the token."},"registerPoolAdapter(address,address)":{"notice":"Registers a pool adapter for a given pool."},"registerStateFingerprintComputer(address,address)":{"notice":"Registers a state fingerprint computer for a given asset."},"setDefaultLOANMetadataUri(string)":{"notice":"Set a default LOAN token metadata uri."},"setFee(uint16)":{"notice":"Set new protocol fee value."},"setFeeCollector(address)":{"notice":"Set new fee collector address."},"setLOANMetadataUri(address,string)":{"notice":"Set a LOAN token metadata uri for a specific loan contract."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/config/PWNConfig.sol":"PWNConfig"},"evmVersion":"london","libraries":{}},"sources":{"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol":{"keccak256":"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510","urls":["bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16","dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"keccak256":"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e","urls":["bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c","dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794","urls":["bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e","dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"keccak256":"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422","urls":["bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b","dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef","urls":["bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95","dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx"],"license":"MIT"},"src/config/PWNConfig.sol":{"keccak256":"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f","urls":["bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7","dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz"],"license":"GPL-3.0-only"},"src/interfaces/IPoolAdapter.sol":{"keccak256":"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89","urls":["bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b","dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T"],"license":"GPL-3.0-only"},"src/interfaces/IStateFingerpringComputer.sol":{"keccak256":"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2","urls":["bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c","dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct"],"license":"GPL-3.0-only"}},"version":1},"id":80} \ No newline at end of file diff --git a/packages/subgraph/abis/Hub.json b/packages/subgraph/abis/Hub.json new file mode 100644 index 00000000..3f419619 --- /dev/null +++ b/packages/subgraph/abis/Hub.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"acceptOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"hasTag","inputs":[{"name":"_address","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"pendingOwner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setTag","inputs":[{"name":"_address","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"},{"name":"_hasTag","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setTags","inputs":[{"name":"_addresses","type":"address[]","internalType":"address[]"},{"name":"_tags","type":"bytes32[]","internalType":"bytes32[]"},{"name":"_hasTag","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TagSet","inputs":[{"name":"_address","type":"address","indexed":true,"internalType":"address"},{"name":"tag","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"hasTag","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"error","name":"InvalidInputData","inputs":[]}],"bytecode":{"object":"0x608060405234801561001057600080fd5b5061001a3361001f565b610096565b600180546001600160a01b031916905561004381610046602090811b61035617901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6106b6806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063d019577a1161005b578063d019577a146100dc578063e30c397814610125578063f12715a114610136578063f2fde38b1461014957600080fd5b8063715018a61461008d57806379ba5097146100975780638da5cb5b1461009f5780639cd9c520146100c9575b600080fd5b61009561015c565b005b610095610170565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100956100d7366004610445565b6101ef565b6101156100ea366004610481565b6001600160a01b03919091166000908152600260209081526040808320938352929052205460ff1690565b60405190151581526020016100c0565b6001546001600160a01b03166100ac565b610095610144366004610581565b610262565b610095610157366004610648565b6102e5565b6101646103a6565b61016e6000610400565b565b60015433906001600160a01b031681146101e35760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6101ec81610400565b50565b6101f76103a6565b6001600160a01b0383166000818152600260209081526040808320868452825291829020805460ff191685151590811790915591519182528492917fb30f662698af140e14b21a677b92bf5a9787f9109294b3d206fa53ea23069d2b910160405180910390a3505050565b61026a6103a6565b815183511461028c57604051637016bd9b60e01b815260040160405180910390fd5b815160005b818110156102de576102d68582815181106102ae576102ae61066a565b60200260200101518583815181106102c8576102c861066a565b6020026020010151856101ef565b600101610291565b5050505050565b6102ed6103a6565b600180546001600160a01b0383166001600160a01b0319909116811790915561031e6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b0316331461016e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101da565b600180546001600160a01b03191690556101ec81610356565b80356001600160a01b038116811461043057600080fd5b919050565b8035801515811461043057600080fd5b60008060006060848603121561045a57600080fd5b61046384610419565b92506020840135915061047860408501610435565b90509250925092565b6000806040838503121561049457600080fd5b61049d83610419565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156104ea576104ea6104ab565b604052919050565b600067ffffffffffffffff82111561050c5761050c6104ab565b5060051b60200190565b600082601f83011261052757600080fd5b8135602061053c610537836104f2565b6104c1565b82815260059290921b8401810191818101908684111561055b57600080fd5b8286015b84811015610576578035835291830191830161055f565b509695505050505050565b60008060006060848603121561059657600080fd5b833567ffffffffffffffff808211156105ae57600080fd5b818601915086601f8301126105c257600080fd5b813560206105d2610537836104f2565b82815260059290921b8401810191818101908a8411156105f157600080fd5b948201945b838610156106165761060786610419565b825294820194908201906105f6565b9750508701359250508082111561062c57600080fd5b5061063986828701610516565b92505061047860408501610435565b60006020828403121561065a57600080fd5b61066382610419565b9392505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220a22c2d5c2ba59f3e59dcc0860c2c2196de14c8ff50cf110a658ccc33011c5cf864736f6c63430008100033","sourceMap":"230:3317:81:-:0;;;1509:37;;;;;;;;;-1:-1:-1;936:32:32;734:10:61;936:18:32;:32::i;:::-;230:3317:81;;1501:153:33;1590:13;1583:20;;-1:-1:-1;;;;;;1583:20:33;;;1613:34;1638:8;1613:24;;;;;;;:34;;:::i;:::-;1501:153;:::o;2426:187:32:-;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:32;;;-1:-1:-1;;;;;;2534:17:32;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;230:3317:81:-;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063d019577a1161005b578063d019577a146100dc578063e30c397814610125578063f12715a114610136578063f2fde38b1461014957600080fd5b8063715018a61461008d57806379ba5097146100975780638da5cb5b1461009f5780639cd9c520146100c9575b600080fd5b61009561015c565b005b610095610170565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100956100d7366004610445565b6101ef565b6101156100ea366004610481565b6001600160a01b03919091166000908152600260209081526040808320938352929052205460ff1690565b60405190151581526020016100c0565b6001546001600160a01b03166100ac565b610095610144366004610581565b610262565b610095610157366004610648565b6102e5565b6101646103a6565b61016e6000610400565b565b60015433906001600160a01b031681146101e35760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6101ec81610400565b50565b6101f76103a6565b6001600160a01b0383166000818152600260209081526040808320868452825291829020805460ff191685151590811790915591519182528492917fb30f662698af140e14b21a677b92bf5a9787f9109294b3d206fa53ea23069d2b910160405180910390a3505050565b61026a6103a6565b815183511461028c57604051637016bd9b60e01b815260040160405180910390fd5b815160005b818110156102de576102d68582815181106102ae576102ae61066a565b60200260200101518583815181106102c8576102c861066a565b6020026020010151856101ef565b600101610291565b5050505050565b6102ed6103a6565b600180546001600160a01b0383166001600160a01b0319909116811790915561031e6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b0316331461016e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101da565b600180546001600160a01b03191690556101ec81610356565b80356001600160a01b038116811461043057600080fd5b919050565b8035801515811461043057600080fd5b60008060006060848603121561045a57600080fd5b61046384610419565b92506020840135915061047860408501610435565b90509250925092565b6000806040838503121561049457600080fd5b61049d83610419565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156104ea576104ea6104ab565b604052919050565b600067ffffffffffffffff82111561050c5761050c6104ab565b5060051b60200190565b600082601f83011261052757600080fd5b8135602061053c610537836104f2565b6104c1565b82815260059290921b8401810191818101908684111561055b57600080fd5b8286015b84811015610576578035835291830191830161055f565b509695505050505050565b60008060006060848603121561059657600080fd5b833567ffffffffffffffff808211156105ae57600080fd5b818601915086601f8301126105c257600080fd5b813560206105d2610537836104f2565b82815260059290921b8401810191818101908a8411156105f157600080fd5b948201945b838610156106165761060786610419565b825294820194908201906105f6565b9750508701359250508082111561062c57600080fd5b5061063986828701610516565b92505061047860408501610435565b60006020828403121561065a57600080fd5b61066382610419565b9392505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220a22c2d5c2ba59f3e59dcc0860c2c2196de14c8ff50cf110a658ccc33011c5cf864736f6c63430008100033","sourceMap":"230:3317:81:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1824:101:32;;;:::i;:::-;;1734:212:33;;;:::i;1201:85:32:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:32;1201:85;;;-1:-1:-1;;;;;178:32:137;;;160:51;;148:2;133:18;1201:85:32;;;;;;;;2069:169:81;;;;;;:::i;:::-;;:::i;3425:119::-;;;;;;:::i;:::-;-1:-1:-1;;;;;3518:14:81;;;;3495:4;3518:14;;;:4;:14;;;;;;;;:19;;;;;;;;;;;3425:119;;;;1316:14:137;;1309:22;1291:41;;1279:2;1264:18;3425:119:81;1151:187:137;847:99:33;926:13;;-1:-1:-1;;;;;926:13:33;847:99;;2594:370:81;;;;;;:::i;:::-;;:::i;1139:178:33:-;;;;;;:::i;:::-;;:::i;1824:101:32:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;1734:212:33:-;926:13;;734:10:61;;-1:-1:-1;;;;;926:13:33;1833:24;;1825:78;;;;-1:-1:-1;;;1825:78:33;;4222:2:137;1825:78:33;;;4204:21:137;4261:2;4241:18;;;4234:30;4300:34;4280:18;;;4273:62;-1:-1:-1;;;4351:18:137;;;4344:39;4400:19;;1825:78:33;;;;;;;;;1913:26;1932:6;1913:18;:26::i;:::-;1776:170;1734:212::o;2069:169:81:-;1094:13:32;:11;:13::i;:::-;-1:-1:-1;;;;;2157:14:81;::::1;;::::0;;;:4:::1;:14;::::0;;;;;;;:19;;;;;;;;;:29;;-1:-1:-1;;2157:29:81::1;::::0;::::1;;::::0;;::::1;::::0;;;2201:30;;1291:41:137;;;2157:19:81;;:14;2201:30:::1;::::0;1264:18:137;2201:30:81::1;;;;;;;2069:169:::0;;;:::o;2594:370::-;1094:13:32;:11;:13::i;:::-;2732:5:81::1;:12;2711:10;:17;:33;2707:76;;2765:18;;-1:-1:-1::0;;;2765:18:81::1;;;;;;;;;;;2707:76;2811:12:::0;;2794:14:::1;2833:125;2853:6;2849:1;:10;2833:125;;;2876:40;2883:10;2894:1;2883:13;;;;;;;;:::i;:::-;;;;;;;2898:5;2904:1;2898:8;;;;;;;;:::i;:::-;;;;;;;2908:7;2876:6;:40::i;:::-;2942:3;;2833:125;;;;2697:267;2594:370:::0;;;:::o;1139:178:33:-;1094:13:32;:11;:13::i;:::-;1228::33::1;:24:::0;;-1:-1:-1;;;;;1228:24:33;::::1;-1:-1:-1::0;;;;;;1228:24:33;;::::1;::::0;::::1;::::0;;;1292:7:::1;1247::32::0;1273:6;-1:-1:-1;;;;;1273:6:32;;1201:85;1292:7:33::1;-1:-1:-1::0;;;;;1267:43:33::1;;;;;;;;;;;1139:178:::0;:::o;2426:187:32:-;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:32;;;-1:-1:-1;;;;;;2534:17:32;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;1359:130::-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:32;734:10:61;1422:23:32;1414:68;;;;-1:-1:-1;;;1414:68:32;;4764:2:137;1414:68:32;;;4746:21:137;;;4783:18;;;4776:30;4842:34;4822:18;;;4815:62;4894:18;;1414:68:32;4562:356:137;1501:153:33;1590:13;1583:20;;-1:-1:-1;;;;;;1583:20:33;;;1613:34;1638:8;1613:24;:34::i;222:173:137:-;290:20;;-1:-1:-1;;;;;339:31:137;;329:42;;319:70;;385:1;382;375:12;319:70;222:173;;;:::o;400:160::-;465:20;;521:13;;514:21;504:32;;494:60;;550:1;547;540:12;565:322;639:6;647;655;708:2;696:9;687:7;683:23;679:32;676:52;;;724:1;721;714:12;676:52;747:29;766:9;747:29;:::i;:::-;737:39;;823:2;812:9;808:18;795:32;785:42;;846:35;877:2;866:9;862:18;846:35;:::i;:::-;836:45;;565:322;;;;;:::o;892:254::-;960:6;968;1021:2;1009:9;1000:7;996:23;992:32;989:52;;;1037:1;1034;1027:12;989:52;1060:29;1079:9;1060:29;:::i;:::-;1050:39;1136:2;1121:18;;;;1108:32;;-1:-1:-1;;;892:254:137:o;1343:127::-;1404:10;1399:3;1395:20;1392:1;1385:31;1435:4;1432:1;1425:15;1459:4;1456:1;1449:15;1475:275;1546:2;1540:9;1611:2;1592:13;;-1:-1:-1;;1588:27:137;1576:40;;1646:18;1631:34;;1667:22;;;1628:62;1625:88;;;1693:18;;:::i;:::-;1729:2;1722:22;1475:275;;-1:-1:-1;1475:275:137:o;1755:183::-;1815:4;1848:18;1840:6;1837:30;1834:56;;;1870:18;;:::i;:::-;-1:-1:-1;1915:1:137;1911:14;1927:4;1907:25;;1755:183::o;1943:662::-;1997:5;2050:3;2043:4;2035:6;2031:17;2027:27;2017:55;;2068:1;2065;2058:12;2017:55;2104:6;2091:20;2130:4;2154:60;2170:43;2210:2;2170:43;:::i;:::-;2154:60;:::i;:::-;2248:15;;;2334:1;2330:10;;;;2318:23;;2314:32;;;2279:12;;;;2358:15;;;2355:35;;;2386:1;2383;2376:12;2355:35;2422:2;2414:6;2410:15;2434:142;2450:6;2445:3;2442:15;2434:142;;;2516:17;;2504:30;;2554:12;;;;2467;;2434:142;;;-1:-1:-1;2594:5:137;1943:662;-1:-1:-1;;;;;;1943:662:137:o;2610:1214::-;2734:6;2742;2750;2803:2;2791:9;2782:7;2778:23;2774:32;2771:52;;;2819:1;2816;2809:12;2771:52;2859:9;2846:23;2888:18;2929:2;2921:6;2918:14;2915:34;;;2945:1;2942;2935:12;2915:34;2983:6;2972:9;2968:22;2958:32;;3028:7;3021:4;3017:2;3013:13;3009:27;2999:55;;3050:1;3047;3040:12;2999:55;3086:2;3073:16;3108:4;3132:60;3148:43;3188:2;3148:43;:::i;3132:60::-;3226:15;;;3308:1;3304:10;;;;3296:19;;3292:28;;;3257:12;;;;3332:19;;;3329:39;;;3364:1;3361;3354:12;3329:39;3388:11;;;;3408:148;3424:6;3419:3;3416:15;3408:148;;;3490:23;3509:3;3490:23;:::i;:::-;3478:36;;3441:12;;;;3534;;;;3408:148;;;3575:5;-1:-1:-1;;3618:18:137;;3605:32;;-1:-1:-1;;3649:16:137;;;3646:36;;;3678:1;3675;3668:12;3646:36;;3701:63;3756:7;3745:8;3734:9;3730:24;3701:63;:::i;:::-;3691:73;;;3783:35;3814:2;3803:9;3799:18;3783:35;:::i;3829:186::-;3888:6;3941:2;3929:9;3920:7;3916:23;3912:32;3909:52;;;3957:1;3954;3947:12;3909:52;3980:29;3999:9;3980:29;:::i;:::-;3970:39;3829:186;-1:-1:-1;;;3829:186:137:o;4430:127::-;4491:10;4486:3;4482:20;4479:1;4472:31;4522:4;4519:1;4512:15;4546:4;4543:1;4536:15","linkReferences":{}},"methodIdentifiers":{"acceptOwnership()":"79ba5097","hasTag(address,bytes32)":"d019577a","owner()":"8da5cb5b","pendingOwner()":"e30c3978","renounceOwnership()":"715018a6","setTag(address,bytes32,bool)":"9cd9c520","setTags(address[],bytes32[],bool)":"f12715a1","transferOwnership(address)":"f2fde38b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidInputData\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasTag\",\"type\":\"bool\"}],\"name\":\"TagSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"hasTag\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"_hasTag\",\"type\":\"bool\"}],\"name\":\"setTag\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_tags\",\"type\":\"bytes32[]\"},{\"internalType\":\"bool\",\"name\":\"_hasTag\",\"type\":\"bool\"}],\"name\":\"setTags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"hasTag(address,bytes32)\":{\"details\":\"Return if an address is associated with a tag.\",\"params\":{\"_address\":\"Address that is examined for a `tag`.\",\"tag\":\"Tag that should an `_address` be associated with.\"},\"returns\":{\"_0\":\"True if given address has a tag.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTag(address,bytes32,bool)\":{\"details\":\"Tag can be added or removed via this functions. Only callable by contract owner.\",\"params\":{\"_address\":\"Address to which a tag is set.\",\"_hasTag\":\"Bool value if tag is added or removed.\",\"tag\":\"Tag that is set to an `_address`.\"}},\"setTags(address[],bytes32[],bool)\":{\"details\":\"Tags can be added or removed via this functions. Only callable by contract owner.\",\"params\":{\"_addresses\":\"List of addresses to which tags are set.\",\"_hasTag\":\"Bool value if tags are added or removed.\",\"_tags\":\"List of tags that are set to an `_address`.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"stateVariables\":{\"tags\":{\"details\":\"Mapping of address tags. (contract address => tag => is tagged)\"}},\"title\":\"PWN Hub\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidInputData()\":[{\"notice\":\"Thrown when `PWNHub.setTags` inputs lengths are not equal.\"}]},\"events\":{\"TagSet(address,bytes32,bool)\":{\"notice\":\"Emitted when tag is set for an address.\"}},\"kind\":\"user\",\"methods\":{\"setTag(address,bytes32,bool)\":{\"notice\":\"Set tag to an address.\"},\"setTags(address[],bytes32[],bool)\":{\"notice\":\"Set list of tags to an address.\"}},\"notice\":\"Connects PWN contracts together into protocol via tags.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/hub/PWNHub.sol\":\"PWNHub\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"type":"error","name":"InvalidInputData"},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferStarted","anonymous":false},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferred","anonymous":false},{"inputs":[{"internalType":"address","name":"_address","type":"address","indexed":true},{"internalType":"bytes32","name":"tag","type":"bytes32","indexed":true},{"internalType":"bool","name":"hasTag","type":"bool","indexed":false}],"type":"event","name":"TagSet","anonymous":false},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"acceptOwnership"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"}],"stateMutability":"view","type":"function","name":"hasTag","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"renounceOwnership"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"},{"internalType":"bool","name":"_hasTag","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setTag"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"internalType":"bytes32[]","name":"_tags","type":"bytes32[]"},{"internalType":"bool","name":"_hasTag","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setTags"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"transferOwnership"}],"devdoc":{"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"hasTag(address,bytes32)":{"details":"Return if an address is associated with a tag.","params":{"_address":"Address that is examined for a `tag`.","tag":"Tag that should an `_address` be associated with."},"returns":{"_0":"True if given address has a tag."}},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."},"setTag(address,bytes32,bool)":{"details":"Tag can be added or removed via this functions. Only callable by contract owner.","params":{"_address":"Address to which a tag is set.","_hasTag":"Bool value if tag is added or removed.","tag":"Tag that is set to an `_address`."}},"setTags(address[],bytes32[],bool)":{"details":"Tags can be added or removed via this functions. Only callable by contract owner.","params":{"_addresses":"List of addresses to which tags are set.","_hasTag":"Bool value if tags are added or removed.","_tags":"List of tags that are set to an `_address`."}},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner."}},"version":1},"userdoc":{"kind":"user","methods":{"setTag(address,bytes32,bool)":{"notice":"Set tag to an address."},"setTags(address[],bytes32[],bool)":{"notice":"Set list of tags to an address."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/hub/PWNHub.sol":"PWNHub"},"evmVersion":"london","libraries":{}},"sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"}},"version":1},"id":81} \ No newline at end of file diff --git a/packages/subgraph/abis/LoanToken.json b/packages/subgraph/abis/LoanToken.json new file mode 100644 index 00000000..63cd0c73 --- /dev/null +++ b/packages/subgraph/abis/LoanToken.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"_hub","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"approve","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"balanceOf","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"burn","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"getApproved","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getStateFingerprint","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"hub","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNHub"}],"stateMutability":"view"},{"type":"function","name":"isApprovedForAll","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"lastLoanId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"loanContract","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"mint","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"ownerOf","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"safeTransferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"safeTransferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setApprovalForAll","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"tokenURI","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"transferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ApprovalForAll","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"LOANBurned","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"LOANMinted","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"loanContract","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"CallerMissingHubTag","inputs":[{"name":"tag","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidLoanContractCaller","inputs":[]}],"bytecode":{"object":"0x60a06040523480156200001157600080fd5b5060405162001893380380620018938339810160408190526200003491620000a7565b60405180604001604052806008815260200167282ba7102627a0a760c11b815250604051806040016040528060048152602001632627a0a760e11b81525081600090816200008391906200017e565b5060016200009282826200017e565b5050506001600160a01b03166080526200024a565b600060208284031215620000ba57600080fd5b81516001600160a01b0381168114620000d257600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200010457607f821691505b6020821081036200012557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200017957600081815260208120601f850160051c81016020861015620001545750805b601f850160051c820191505b81811015620001755782815560010162000160565b5050505b505050565b81516001600160401b038111156200019a576200019a620000d9565b620001b281620001ab8454620000ef565b846200012b565b602080601f831160018114620001ea5760008415620001d15750858301515b600019600386901b1c1916600185901b17855562000175565b600085815260208120601f198616915b828110156200021b57888601518255948401946001909101908401620001fa565b50858210156200023a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516116266200026d600039600081816101bb015261067f01526116266000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806368be92b4116100ad578063a22cb46511610071578063a22cb46514610284578063b88d4fde14610297578063c87b56dd146102aa578063e985e9c5146102bd578063f5112315146102f957600080fd5b806368be92b4146102165780636a6278421461022d57806370a082311461024057806395d89b4114610253578063a00d21fc1461025b57600080fd5b806323b872dd116100f457806323b872dd146101a3578063365a86fc146101b657806342842e0e146101dd57806342966c68146101f05780636352211e1461020357600080fd5b806301ffc9a71461012657806306fdde031461014e578063081812fc14610163578063095ea7b31461018e575b600080fd5b6101396101343660046110dc565b61030c565b60405190151581526020015b60405180910390f35b610156610338565b6040516101459190611149565b61017661017136600461115c565b6103ca565b6040516001600160a01b039091168152602001610145565b6101a161019c366004611191565b6103f1565b005b6101a16101b13660046111bb565b61050b565b6101767f000000000000000000000000000000000000000000000000000000000000000081565b6101a16101eb3660046111bb565b61053c565b6101a16101fe36600461115c565b610557565b61017661021136600461115c565b6105e1565b61021f60065481565b604051908152602001610145565b61021f61023b3660046111f7565b610641565b61021f61024e3660046111f7565b6107ac565b610156610832565b61017661026936600461115c565b6007602052600090815260409020546001600160a01b031681565b6101a1610292366004611220565b610841565b6101a16102a53660046112c6565b610850565b6101566102b836600461115c565b610888565b6101396102cb366004611371565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61021f61030736600461115c565b61090b565b6000610317826109a1565b8061033257506001600160e01b0319821663f511231560e01b145b92915050565b606060008054610347906113a4565b80601f0160208091040260200160405190810160405280929190818152602001828054610373906113a4565b80156103c05780601f10610395576101008083540402835291602001916103c0565b820191906000526020600020905b8154815290600101906020018083116103a357829003601f168201915b5050505050905090565b60006103d5826109f1565b506000908152600460205260409020546001600160a01b031690565b60006103fc826105e1565b9050806001600160a01b0316836001600160a01b03160361046e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061048a575061048a81336102cb565b6104fc5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610465565b6105068383610a53565b505050565b6105153382610ac1565b6105315760405162461bcd60e51b8152600401610465906113de565b610506838383610b40565b61050683838360405180602001604052806000815250610850565b6000818152600760205260409020546001600160a01b0316331461058e576040516374768c4960e11b815260040160405180910390fd5b600081815260076020526040902080546001600160a01b03191690556105b381610ca4565b60405181907f56f7da88d3aa2a8ad74b71a5b449a66a643193815eace8bbd6b089d4bc18294b90600090a250565b6000818152600260205260408120546001600160a01b0316806103325760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b60405163680cabbd60e11b81523360048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d019577a90604401602060405180830381865afa1580156106ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f2919061142b565b6107315760405163f8932b2d60e01b81527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946004820152602401610465565b60066000815461074090611448565b9182905550600081815260076020526040902080546001600160a01b03191633179055905061076f8282610d39565b6040516001600160a01b03831690339083907f2ca529bede83c064afd9331357a1ce320271c9c7ceda28ac31472d76f7aff53090600090a4919050565b60006001600160a01b0382166108165760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610465565b506001600160a01b031660009081526003602052604090205490565b606060018054610347906113a4565b61084c338383610ec4565b5050565b61085a3383610ac1565b6108765760405162461bcd60e51b8152600401610465906113de565b61088284848484610f92565b50505050565b6060610893826109f1565b60008281526007602052604080822054815163111d8a1560e01b815291516001600160a01b039091169263111d8a1592600480820193918290030181865afa1580156108e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610332919081019061146f565b6000818152600760205260408120546001600160a01b0316806109315750600092915050565b60405163f511231560e01b8152600481018490526001600160a01b0382169063f511231590602401602060405180830381865afa158015610976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099a91906114e6565b9392505050565b60006001600160e01b031982166380ac58cd60e01b14806109d257506001600160e01b03198216635b5e139f60e01b145b8061033257506301ffc9a760e01b6001600160e01b0319831614610332565b6000818152600260205260409020546001600160a01b0316610a505760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610a88826105e1565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610acd836105e1565b9050806001600160a01b0316846001600160a01b03161480610b1457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610b385750836001600160a01b0316610b2d846103ca565b6001600160a01b0316145b949350505050565b826001600160a01b0316610b53826105e1565b6001600160a01b031614610b795760405162461bcd60e51b8152600401610465906114ff565b6001600160a01b038216610bdb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610465565b826001600160a01b0316610bee826105e1565b6001600160a01b031614610c145760405162461bcd60e51b8152600401610465906114ff565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610caf826105e1565b9050610cba826105e1565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b038216610d8f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610465565b6000818152600260205260409020546001600160a01b031615610df45760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6000818152600260205260409020546001600160a01b031615610e595760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610f255760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610465565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610f9d848484610b40565b610fa984848484610fc5565b6108825760405162461bcd60e51b815260040161046590611544565b60006001600160a01b0384163b156110bb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611009903390899088908890600401611596565b6020604051808303816000875af1925050508015611044575060408051601f3d908101601f19168201909252611041918101906115d3565b60015b6110a1573d808015611072576040519150601f19603f3d011682016040523d82523d6000602084013e611077565b606091505b5080516000036110995760405162461bcd60e51b815260040161046590611544565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610b38565b506001949350505050565b6001600160e01b031981168114610a5057600080fd5b6000602082840312156110ee57600080fd5b813561099a816110c6565b60005b838110156111145781810151838201526020016110fc565b50506000910152565b600081518084526111358160208601602086016110f9565b601f01601f19169290920160200192915050565b60208152600061099a602083018461111d565b60006020828403121561116e57600080fd5b5035919050565b80356001600160a01b038116811461118c57600080fd5b919050565b600080604083850312156111a457600080fd5b6111ad83611175565b946020939093013593505050565b6000806000606084860312156111d057600080fd5b6111d984611175565b92506111e760208501611175565b9150604084013590509250925092565b60006020828403121561120957600080fd5b61099a82611175565b8015158114610a5057600080fd5b6000806040838503121561123357600080fd5b61123c83611175565b9150602083013561124c81611212565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561129657611296611257565b604052919050565b600067ffffffffffffffff8211156112b8576112b8611257565b50601f01601f191660200190565b600080600080608085870312156112dc57600080fd5b6112e585611175565b93506112f360208601611175565b925060408501359150606085013567ffffffffffffffff81111561131657600080fd5b8501601f8101871361132757600080fd5b803561133a6113358261129e565b61126d565b81815288602083850101111561134f57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561138457600080fd5b61138d83611175565b915061139b60208401611175565b90509250929050565b600181811c908216806113b857607f821691505b6020821081036113d857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60006020828403121561143d57600080fd5b815161099a81611212565b60006001820161146857634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121561148157600080fd5b815167ffffffffffffffff81111561149857600080fd5b8201601f810184136114a957600080fd5b80516114b76113358261129e565b8181528560208385010111156114cc57600080fd5b6114dd8260208301602086016110f9565b95945050505050565b6000602082840312156114f857600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906115c99083018461111d565b9695505050505050565b6000602082840312156115e557600080fd5b815161099a816110c656fea2646970667358221220b7de9ec72201d73c775ea864f50f9ddf2db4959b34b068baf1f629cef092f01864736f6c63430008100033","sourceMap":"635:5123:100:-:0;;;2752:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1390:113:56;;;;;;;;;;;;;-1:-1:-1;;;1390:113:56;;;;;;;;;;;;;;;;-1:-1:-1;;;1390:113:56;;;1464:5;1456;:13;;;;;;:::i;:::-;-1:-1:-1;1479:7:56;:17;1489:7;1479;:17;:::i;:::-;-1:-1:-1;;;;;;;;2815:18:100::1;;::::0;635:5123;;14:290:137;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;179:16;;-1:-1:-1;;;;;224:31:137;;214:42;;204:70;;270:1;267;260:12;204:70;293:5;14:290;-1:-1:-1;;;14:290:137:o;309:127::-;370:10;365:3;361:20;358:1;351:31;401:4;398:1;391:15;425:4;422:1;415:15;441:380;520:1;516:12;;;;563;;;584:61;;638:4;630:6;626:17;616:27;;584:61;691:2;683:6;680:14;660:18;657:38;654:161;;737:10;732:3;728:20;725:1;718:31;772:4;769:1;762:15;800:4;797:1;790:15;654:161;;441:380;;;:::o;952:545::-;1054:2;1049:3;1046:11;1043:448;;;1090:1;1115:5;1111:2;1104:17;1160:4;1156:2;1146:19;1230:2;1218:10;1214:19;1211:1;1207:27;1201:4;1197:38;1266:4;1254:10;1251:20;1248:47;;;-1:-1:-1;1289:4:137;1248:47;1344:2;1339:3;1335:12;1332:1;1328:20;1322:4;1318:31;1308:41;;1399:82;1417:2;1410:5;1407:13;1399:82;;;1462:17;;;1443:1;1432:13;1399:82;;;1403:3;;;1043:448;952:545;;;:::o;1673:1352::-;1793:10;;-1:-1:-1;;;;;1815:30:137;;1812:56;;;1848:18;;:::i;:::-;1877:97;1967:6;1927:38;1959:4;1953:11;1927:38;:::i;:::-;1921:4;1877:97;:::i;:::-;2029:4;;2093:2;2082:14;;2110:1;2105:663;;;;2812:1;2829:6;2826:89;;;-1:-1:-1;2881:19:137;;;2875:26;2826:89;-1:-1:-1;;1630:1:137;1626:11;;;1622:24;1618:29;1608:40;1654:1;1650:11;;;1605:57;2928:81;;2075:944;;2105:663;899:1;892:14;;;936:4;923:18;;-1:-1:-1;;2141:20:137;;;2259:236;2273:7;2270:1;2267:14;2259:236;;;2362:19;;;2356:26;2341:42;;2454:27;;;;2422:1;2410:14;;;;2289:19;;2259:236;;;2263:3;2523:6;2514:7;2511:19;2508:201;;;2584:19;;;2578:26;-1:-1:-1;;2667:1:137;2663:14;;;2679:3;2659:24;2655:37;2651:42;2636:58;2621:74;;2508:201;-1:-1:-1;;;;;2755:1:137;2739:14;;;2735:22;2722:36;;-1:-1:-1;1673:1352:137:o;:::-;635:5123:100;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106101215760003560e01c806368be92b4116100ad578063a22cb46511610071578063a22cb46514610284578063b88d4fde14610297578063c87b56dd146102aa578063e985e9c5146102bd578063f5112315146102f957600080fd5b806368be92b4146102165780636a6278421461022d57806370a082311461024057806395d89b4114610253578063a00d21fc1461025b57600080fd5b806323b872dd116100f457806323b872dd146101a3578063365a86fc146101b657806342842e0e146101dd57806342966c68146101f05780636352211e1461020357600080fd5b806301ffc9a71461012657806306fdde031461014e578063081812fc14610163578063095ea7b31461018e575b600080fd5b6101396101343660046110dc565b61030c565b60405190151581526020015b60405180910390f35b610156610338565b6040516101459190611149565b61017661017136600461115c565b6103ca565b6040516001600160a01b039091168152602001610145565b6101a161019c366004611191565b6103f1565b005b6101a16101b13660046111bb565b61050b565b6101767f000000000000000000000000000000000000000000000000000000000000000081565b6101a16101eb3660046111bb565b61053c565b6101a16101fe36600461115c565b610557565b61017661021136600461115c565b6105e1565b61021f60065481565b604051908152602001610145565b61021f61023b3660046111f7565b610641565b61021f61024e3660046111f7565b6107ac565b610156610832565b61017661026936600461115c565b6007602052600090815260409020546001600160a01b031681565b6101a1610292366004611220565b610841565b6101a16102a53660046112c6565b610850565b6101566102b836600461115c565b610888565b6101396102cb366004611371565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61021f61030736600461115c565b61090b565b6000610317826109a1565b8061033257506001600160e01b0319821663f511231560e01b145b92915050565b606060008054610347906113a4565b80601f0160208091040260200160405190810160405280929190818152602001828054610373906113a4565b80156103c05780601f10610395576101008083540402835291602001916103c0565b820191906000526020600020905b8154815290600101906020018083116103a357829003601f168201915b5050505050905090565b60006103d5826109f1565b506000908152600460205260409020546001600160a01b031690565b60006103fc826105e1565b9050806001600160a01b0316836001600160a01b03160361046e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061048a575061048a81336102cb565b6104fc5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610465565b6105068383610a53565b505050565b6105153382610ac1565b6105315760405162461bcd60e51b8152600401610465906113de565b610506838383610b40565b61050683838360405180602001604052806000815250610850565b6000818152600760205260409020546001600160a01b0316331461058e576040516374768c4960e11b815260040160405180910390fd5b600081815260076020526040902080546001600160a01b03191690556105b381610ca4565b60405181907f56f7da88d3aa2a8ad74b71a5b449a66a643193815eace8bbd6b089d4bc18294b90600090a250565b6000818152600260205260408120546001600160a01b0316806103325760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b60405163680cabbd60e11b81523360048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d019577a90604401602060405180830381865afa1580156106ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f2919061142b565b6107315760405163f8932b2d60e01b81527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946004820152602401610465565b60066000815461074090611448565b9182905550600081815260076020526040902080546001600160a01b03191633179055905061076f8282610d39565b6040516001600160a01b03831690339083907f2ca529bede83c064afd9331357a1ce320271c9c7ceda28ac31472d76f7aff53090600090a4919050565b60006001600160a01b0382166108165760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610465565b506001600160a01b031660009081526003602052604090205490565b606060018054610347906113a4565b61084c338383610ec4565b5050565b61085a3383610ac1565b6108765760405162461bcd60e51b8152600401610465906113de565b61088284848484610f92565b50505050565b6060610893826109f1565b60008281526007602052604080822054815163111d8a1560e01b815291516001600160a01b039091169263111d8a1592600480820193918290030181865afa1580156108e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610332919081019061146f565b6000818152600760205260408120546001600160a01b0316806109315750600092915050565b60405163f511231560e01b8152600481018490526001600160a01b0382169063f511231590602401602060405180830381865afa158015610976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099a91906114e6565b9392505050565b60006001600160e01b031982166380ac58cd60e01b14806109d257506001600160e01b03198216635b5e139f60e01b145b8061033257506301ffc9a760e01b6001600160e01b0319831614610332565b6000818152600260205260409020546001600160a01b0316610a505760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610a88826105e1565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610acd836105e1565b9050806001600160a01b0316846001600160a01b03161480610b1457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610b385750836001600160a01b0316610b2d846103ca565b6001600160a01b0316145b949350505050565b826001600160a01b0316610b53826105e1565b6001600160a01b031614610b795760405162461bcd60e51b8152600401610465906114ff565b6001600160a01b038216610bdb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610465565b826001600160a01b0316610bee826105e1565b6001600160a01b031614610c145760405162461bcd60e51b8152600401610465906114ff565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610caf826105e1565b9050610cba826105e1565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b038216610d8f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610465565b6000818152600260205260409020546001600160a01b031615610df45760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6000818152600260205260409020546001600160a01b031615610e595760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610f255760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610465565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610f9d848484610b40565b610fa984848484610fc5565b6108825760405162461bcd60e51b815260040161046590611544565b60006001600160a01b0384163b156110bb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611009903390899088908890600401611596565b6020604051808303816000875af1925050508015611044575060408051601f3d908101601f19168201909252611041918101906115d3565b60015b6110a1573d808015611072576040519150601f19603f3d011682016040523d82523d6000602084013e611077565b606091505b5080516000036110995760405162461bcd60e51b815260040161046590611544565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610b38565b506001949350505050565b6001600160e01b031981168114610a5057600080fd5b6000602082840312156110ee57600080fd5b813561099a816110c6565b60005b838110156111145781810151838201526020016110fc565b50506000910152565b600081518084526111358160208601602086016110f9565b601f01601f19169290920160200192915050565b60208152600061099a602083018461111d565b60006020828403121561116e57600080fd5b5035919050565b80356001600160a01b038116811461118c57600080fd5b919050565b600080604083850312156111a457600080fd5b6111ad83611175565b946020939093013593505050565b6000806000606084860312156111d057600080fd5b6111d984611175565b92506111e760208501611175565b9150604084013590509250925092565b60006020828403121561120957600080fd5b61099a82611175565b8015158114610a5057600080fd5b6000806040838503121561123357600080fd5b61123c83611175565b9150602083013561124c81611212565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561129657611296611257565b604052919050565b600067ffffffffffffffff8211156112b8576112b8611257565b50601f01601f191660200190565b600080600080608085870312156112dc57600080fd5b6112e585611175565b93506112f360208601611175565b925060408501359150606085013567ffffffffffffffff81111561131657600080fd5b8501601f8101871361132757600080fd5b803561133a6113358261129e565b61126d565b81815288602083850101111561134f57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561138457600080fd5b61138d83611175565b915061139b60208401611175565b90509250929050565b600181811c908216806113b857607f821691505b6020821081036113d857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60006020828403121561143d57600080fd5b815161099a81611212565b60006001820161146857634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121561148157600080fd5b815167ffffffffffffffff81111561149857600080fd5b8201601f810184136114a957600080fd5b80516114b76113358261129e565b8181528560208385010111156114cc57600080fd5b6114dd8260208301602086016110f9565b95945050505050565b6000602082840312156114f857600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906115c99083018461111d565b9695505050505050565b6000602082840312156115e557600080fd5b815161099a816110c656fea2646970667358221220b7de9ec72201d73c775ea864f50f9ddf2db4959b34b068baf1f629cef092f01864736f6c63430008100033","sourceMap":"635:5123:100:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5547:208;;;;;;:::i;:::-;;:::i;:::-;;;565:14:137;;558:22;540:41;;528:2;513:18;5547:208:100;;;;;;;;2471:98:56;;;:::i;:::-;;;;;;;:::i;3935:167::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:137;;;1679:51;;1667:2;1652:18;3935:167:56;1533:203:137;3468:406:56;;;;;;:::i;:::-;;:::i;:::-;;4612:296;;;;;;:::i;:::-;;:::i;881:27:100:-;;;;;4974:149:56;;;;;;:::i;:::-;;:::i;3837:236:100:-;;;;;;:::i;:::-;;:::i;2190:219:56:-;;;;;;:::i;:::-;;:::i;1009:25:100:-;;;;;;;;;2881::137;;;2869:2;2854:18;1009:25:100;2735:177:137;3309:241:100;;;;;;:::i;:::-;;:::i;1929:204:56:-;;;;;;:::i;:::-;;:::i;2633:102::-;;;:::i;1137:48:100:-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1137:48:100;;;4169:153:56;;;;;;:::i;:::-;;:::i;5189:276::-;;;;;;:::i;:::-;;:::i;4493:211:100:-;;;;;;:::i;:::-;;:::i;4388:162:56:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4508:25:56;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4388:162;4977:300:100;;;;;;:::i;:::-;;:::i;5547:208::-;5632:4;5655:36;5679:11;5655:23;:36::i;:::-;:93;;;-1:-1:-1;;;;;;;5707:41:100;;-1:-1:-1;;;5707:41:100;5655:93;5648:100;5547:208;-1:-1:-1;;5547:208:100:o;2471:98:56:-;2525:13;2557:5;2550:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2471:98;:::o;3935:167::-;4011:7;4030:23;4045:7;4030:14;:23::i;:::-;-1:-1:-1;4071:24:56;;;;:15;:24;;;;;;-1:-1:-1;;;;;4071:24:56;;3935:167::o;3468:406::-;3548:13;3564:23;3579:7;3564:14;:23::i;:::-;3548:39;;3611:5;-1:-1:-1;;;;;3605:11:56;:2;-1:-1:-1;;;;;3605:11:56;;3597:57;;;;-1:-1:-1;;;3597:57:56;;6081:2:137;3597:57:56;;;6063:21:137;6120:2;6100:18;;;6093:30;6159:34;6139:18;;;6132:62;-1:-1:-1;;;6210:18:137;;;6203:31;6251:19;;3597:57:56;;;;;;;;;734:10:61;-1:-1:-1;;;;;3686:21:56;;;;:62;;-1:-1:-1;3711:37:56;3728:5;734:10:61;4388:162:56;:::i;3711:37::-;3665:170;;;;-1:-1:-1;;;3665:170:56;;6483:2:137;3665:170:56;;;6465:21:137;6522:2;6502:18;;;6495:30;6561:34;6541:18;;;6534:62;6632:31;6612:18;;;6605:59;6681:19;;3665:170:56;6281:425:137;3665:170:56;3846:21;3855:2;3859:7;3846:8;:21::i;:::-;3538:336;3468:406;;:::o;4612:296::-;4771:41;734:10:61;4804:7:56;4771:18;:41::i;:::-;4763:99;;;;-1:-1:-1;;;4763:99:56;;;;;;;:::i;:::-;4873:28;4883:4;4889:2;4893:7;4873:9;:28::i;4974:149::-;5077:39;5094:4;5100:2;5104:7;5077:39;;;;;;;;;;;;:16;:39::i;3837:236:100:-;3890:20;;;;:12;:20;;;;;;-1:-1:-1;;;;;3890:20:100;3914:10;3890:34;3886:86;;3945:27;;-1:-1:-1;;;3945:27:100;;;;;;;;;;;3886:86;3990:20;;;;:12;:20;;;;;3983:27;;-1:-1:-1;;;;;;3983:27:100;;;4020:13;4003:6;4020:5;:13::i;:::-;4048:18;;4059:6;;4048:18;;;;;3837:236;:::o;2190:219:56:-;2262:7;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;;2324:56;;;;-1:-1:-1;;;2324:56:56;;7327:2:137;2324:56:56;;;7309:21:137;7366:2;7346:18;;;7339:30;-1:-1:-1;;;7385:18:137;;;7378:54;7449:18;;2324:56:56;7125:348:137;3309:241:100;2406:46;;-1:-1:-1;;;2406:46:100;;2417:10;2406:46;;;7652:51:137;266:28:82;7719:18:137;;;7712:34;3371:14:100;;2406:3;-1:-1:-1;;;;;2406:10:100;;;;7625:18:137;;2406:46:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2401:124;;2473:52;;-1:-1:-1;;;2473:52:100;;266:28:82;2473:52:100;;;2881:25:137;2854:18;;2473:52:100;2735:177:137;2401:124:100;3408:10:::1;;3406:12;;;;;:::i;:::-;::::0;;;;-1:-1:-1;3428:20:100::1;::::0;;;:12:::1;:20;::::0;;;;:33;;-1:-1:-1;;;;;;3428:33:100::1;3451:10;3428:33;::::0;;3406:12;-1:-1:-1;3471:20:100::1;3477:5:::0;3406:12;3471:5:::1;:20::i;:::-;3506:37;::::0;-1:-1:-1;;;;;3506:37:100;::::1;::::0;3525:10:::1;::::0;3517:6;;3506:37:::1;::::0;;;::::1;3309:241:::0;;;:::o;1929:204:56:-;2001:7;-1:-1:-1;;;;;2028:19:56;;2020:73;;;;-1:-1:-1;;;2020:73:56;;8446:2:137;2020:73:56;;;8428:21:137;8485:2;8465:18;;;8458:30;8524:34;8504:18;;;8497:62;-1:-1:-1;;;8575:18:137;;;8568:39;8624:19;;2020:73:56;8244:405:137;2020:73:56;-1:-1:-1;;;;;;2110:16:56;;;;;:9;:16;;;;;;;1929:204::o;2633:102::-;2689:13;2721:7;2714:14;;;;;:::i;4169:153::-;4263:52;734:10:61;4296:8:56;4306;4263:18;:52::i;:::-;4169:153;;:::o;5189:276::-;5319:41;734:10:61;5352:7:56;5319:18;:41::i;:::-;5311:99;;;;-1:-1:-1;;;5311:99:56;;;;;;;:::i;:::-;5420:38;5434:4;5440:2;5444:7;5453:4;5420:13;:38::i;:::-;5189:276;;;;:::o;4493:211:100:-;4566:13;4591:23;4606:7;4591:14;:23::i;:::-;4657:21;;;;:12;:21;;;;;;;4632:65;;-1:-1:-1;;;4632:65:100;;;;-1:-1:-1;;;;;4657:21:100;;;;4632:63;;:65;;;;;;;;;;;4657:21;4632:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4632:65:100;;;;;;;;;;;;:::i;4977:300::-;5063:7;5106:21;;;:12;:21;;;;;;-1:-1:-1;;;;;5106:21:100;;5138:62;;-1:-1:-1;5198:1:100;;4977:300;-1:-1:-1;;4977:300:100:o;5138:62::-;5218:52;;-1:-1:-1;;;5218:52:100;;;;;2881:25:137;;;-1:-1:-1;;;;;5218:43:100;;;;;2854:18:137;;5218:52:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5211:59;4977:300;-1:-1:-1;;;4977:300:100:o;1570::56:-;1672:4;-1:-1:-1;;;;;;1707:40:56;;-1:-1:-1;;;1707:40:56;;:104;;-1:-1:-1;;;;;;;1763:48:56;;-1:-1:-1;;;1763:48:56;1707:104;:156;;;-1:-1:-1;;;;;;;;;;937:40:67;;;1827:36:56;829:155:67;13240:133:56;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;13313:53;;;;-1:-1:-1;;;13313:53:56;;7327:2:137;13313:53:56;;;7309:21:137;7366:2;7346:18;;;7339:30;-1:-1:-1;;;7385:18:137;;;7378:54;7449:18;;13313:53:56;7125:348:137;13313:53:56;13240:133;:::o;12572:171::-;12646:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;12646:29:56;-1:-1:-1;;;;;12646:29:56;;;;;;;;:24;;12699:23;12646:24;12699:14;:23::i;:::-;-1:-1:-1;;;;;12690:46:56;;;;;;;;;;;12572:171;;:::o;7404:261::-;7497:4;7513:13;7529:23;7544:7;7529:14;:23::i;:::-;7513:39;;7581:5;-1:-1:-1;;;;;7570:16:56;:7;-1:-1:-1;;;;;7570:16:56;;:52;;;-1:-1:-1;;;;;;4508:25:56;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7590:32;7570:87;;;;7650:7;-1:-1:-1;;;;;7626:31:56;:20;7638:7;7626:11;:20::i;:::-;-1:-1:-1;;;;;7626:31:56;;7570:87;7562:96;7404:261;-1:-1:-1;;;;7404:261:56:o;11257:1203::-;11381:4;-1:-1:-1;;;;;11354:31:56;:23;11369:7;11354:14;:23::i;:::-;-1:-1:-1;;;;;11354:31:56;;11346:81;;;;-1:-1:-1;;;11346:81:56;;;;;;;:::i;:::-;-1:-1:-1;;;;;11445:16:56;;11437:65;;;;-1:-1:-1;;;11437:65:56;;10104:2:137;11437:65:56;;;10086:21:137;10143:2;10123:18;;;10116:30;10182:34;10162:18;;;10155:62;-1:-1:-1;;;10233:18:137;;;10226:34;10277:19;;11437:65:56;9902:400:137;11437:65:56;11682:4;-1:-1:-1;;;;;11655:31:56;:23;11670:7;11655:14;:23::i;:::-;-1:-1:-1;;;;;11655:31:56;;11647:81;;;;-1:-1:-1;;;11647:81:56;;;;;;;:::i;:::-;11797:24;;;;:15;:24;;;;;;;;11790:31;;-1:-1:-1;;;;;;11790:31:56;;;;;;-1:-1:-1;;;;;12265:15:56;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;12265:20:56;;;12299:13;;;;;;;;;:18;;11790:31;12299:18;;;12337:16;;;:7;:16;;;;;;:21;;;;;;;;;;12374:27;;11813:7;;12374:27;;;3538:336;3468:406;;:::o;10171:762::-;10230:13;10246:23;10261:7;10246:14;:23::i;:::-;10230:39;;10441:23;10456:7;10441:14;:23::i;:::-;10509:24;;;;:15;:24;;;;;;;;10502:31;;-1:-1:-1;;;;;;10502:31:56;;;;;;-1:-1:-1;;;;;10749:16:56;;;;;:9;:16;;;;;:21;;-1:-1:-1;;10749:21:56;;;10797:16;;;:7;:16;;;;;;10790:23;;;;;;;10829:36;10433:31;;-1:-1:-1;10525:7:56;;10829:36;;10509:24;;10829:36;4169:153;;:::o;8925:920::-;-1:-1:-1;;;;;9004:16:56;;8996:61;;;;-1:-1:-1;;;8996:61:56;;10509:2:137;8996:61:56;;;10491:21:137;;;10528:18;;;10521:30;10587:34;10567:18;;;10560:62;10639:18;;8996:61:56;10307:356:137;8996:61:56;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;7208:31;9067:58;;;;-1:-1:-1;;;9067:58:56;;10870:2:137;9067:58:56;;;10852:21:137;10909:2;10889:18;;;10882:30;10948;10928:18;;;10921:58;10996:18;;9067:58:56;10668:352:137;9067:58:56;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;7208:31;9271:58;;;;-1:-1:-1;;;9271:58:56;;10870:2:137;9271:58:56;;;10852:21:137;10909:2;10889:18;;;10882:30;10948;10928:18;;;10921:58;10996:18;;9271:58:56;10668:352:137;9271:58:56;-1:-1:-1;;;;;9671:13:56;;;;;;:9;:13;;;;;;;;:18;;9688:1;9671:18;;;9710:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9710:21:56;;;;;9747:33;9718:7;;9671:13;;9747:33;;9671:13;;9747:33;4169:153;;:::o;12879:277::-;12999:8;-1:-1:-1;;;;;12990:17:56;:5;-1:-1:-1;;;;;12990:17:56;;12982:55;;;;-1:-1:-1;;;12982:55:56;;11227:2:137;12982:55:56;;;11209:21:137;11266:2;11246:18;;;11239:30;11305:27;11285:18;;;11278:55;11350:18;;12982:55:56;11025:349:137;12982:55:56;-1:-1:-1;;;;;13047:25:56;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13047:46:56;;;;;;;;;;13108:41;;540::137;;;13108::56;;513:18:137;13108:41:56;;;;;;;12879:277;;;:::o;6326:267::-;6438:28;6448:4;6454:2;6458:7;6438:9;:28::i;:::-;6484:47;6507:4;6513:2;6517:7;6526:4;6484:22;:47::i;:::-;6476:110;;;;-1:-1:-1;;;6476:110:56;;;;;;;:::i;13925:831::-;14074:4;-1:-1:-1;;;;;14094:13:56;;1702:19:60;:23;14090:660:56;;14129:71;;-1:-1:-1;;;14129:71:56;;-1:-1:-1;;;;;14129:36:56;;;;;:71;;734:10:61;;14180:4:56;;14186:7;;14195:4;;14129:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14129:71:56;;;;;;;;-1:-1:-1;;14129:71:56;;;;;;;;;;;;:::i;:::-;;;14125:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14367:6;:13;14384:1;14367:18;14363:321;;14409:60;;-1:-1:-1;;;14409:60:56;;;;;;;:::i;14363:321::-;14636:6;14630:13;14621:6;14617:2;14613:15;14606:38;14125:573;-1:-1:-1;;;;;;14250:51:56;-1:-1:-1;;;14250:51:56;;-1:-1:-1;14243:58:56;;14090:660;-1:-1:-1;14735:4:56;13925:831;;;;;;:::o;14:131:137:-;-1:-1:-1;;;;;;88:32:137;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:137;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:137;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:137:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:137;;1348:180;-1:-1:-1;1348:180:137:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:137;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:137:o;2178:328::-;2255:6;2263;2271;2324:2;2312:9;2303:7;2299:23;2295:32;2292:52;;;2340:1;2337;2330:12;2292:52;2363:29;2382:9;2363:29;:::i;:::-;2353:39;;2411:38;2445:2;2434:9;2430:18;2411:38;:::i;:::-;2401:48;;2496:2;2485:9;2481:18;2468:32;2458:42;;2178:328;;;;;:::o;2917:186::-;2976:6;3029:2;3017:9;3008:7;3004:23;3000:32;2997:52;;;3045:1;3042;3035:12;2997:52;3068:29;3087:9;3068:29;:::i;3108:118::-;3194:5;3187:13;3180:21;3173:5;3170:32;3160:60;;3216:1;3213;3206:12;3231:315;3296:6;3304;3357:2;3345:9;3336:7;3332:23;3328:32;3325:52;;;3373:1;3370;3363:12;3325:52;3396:29;3415:9;3396:29;:::i;:::-;3386:39;;3475:2;3464:9;3460:18;3447:32;3488:28;3510:5;3488:28;:::i;:::-;3535:5;3525:15;;;3231:315;;;;;:::o;3551:127::-;3612:10;3607:3;3603:20;3600:1;3593:31;3643:4;3640:1;3633:15;3667:4;3664:1;3657:15;3683:275;3754:2;3748:9;3819:2;3800:13;;-1:-1:-1;;3796:27:137;3784:40;;3854:18;3839:34;;3875:22;;;3836:62;3833:88;;;3901:18;;:::i;:::-;3937:2;3930:22;3683:275;;-1:-1:-1;3683:275:137:o;3963:186::-;4011:4;4044:18;4036:6;4033:30;4030:56;;;4066:18;;:::i;:::-;-1:-1:-1;4132:2:137;4111:15;-1:-1:-1;;4107:29:137;4138:4;4103:40;;3963:186::o;4154:888::-;4249:6;4257;4265;4273;4326:3;4314:9;4305:7;4301:23;4297:33;4294:53;;;4343:1;4340;4333:12;4294:53;4366:29;4385:9;4366:29;:::i;:::-;4356:39;;4414:38;4448:2;4437:9;4433:18;4414:38;:::i;:::-;4404:48;;4499:2;4488:9;4484:18;4471:32;4461:42;;4554:2;4543:9;4539:18;4526:32;4581:18;4573:6;4570:30;4567:50;;;4613:1;4610;4603:12;4567:50;4636:22;;4689:4;4681:13;;4677:27;-1:-1:-1;4667:55:137;;4718:1;4715;4708:12;4667:55;4754:2;4741:16;4779:48;4795:31;4823:2;4795:31;:::i;:::-;4779:48;:::i;:::-;4850:2;4843:5;4836:17;4890:7;4885:2;4880;4876;4872:11;4868:20;4865:33;4862:53;;;4911:1;4908;4901:12;4862:53;4966:2;4961;4957;4953:11;4948:2;4941:5;4937:14;4924:45;5010:1;5005:2;5000;4993:5;4989:14;4985:23;4978:34;5031:5;5021:15;;;;;4154:888;;;;;;;:::o;5047:260::-;5115:6;5123;5176:2;5164:9;5155:7;5151:23;5147:32;5144:52;;;5192:1;5189;5182:12;5144:52;5215:29;5234:9;5215:29;:::i;:::-;5205:39;;5263:38;5297:2;5286:9;5282:18;5263:38;:::i;:::-;5253:48;;5047:260;;;;;:::o;5494:380::-;5573:1;5569:12;;;;5616;;;5637:61;;5691:4;5683:6;5679:17;5669:27;;5637:61;5744:2;5736:6;5733:14;5713:18;5710:38;5707:161;;5790:10;5785:3;5781:20;5778:1;5771:31;5825:4;5822:1;5815:15;5853:4;5850:1;5843:15;5707:161;;5494:380;;;:::o;6711:409::-;6913:2;6895:21;;;6952:2;6932:18;;;6925:30;6991:34;6986:2;6971:18;;6964:62;-1:-1:-1;;;7057:2:137;7042:18;;7035:43;7110:3;7095:19;;6711:409::o;7757:245::-;7824:6;7877:2;7865:9;7856:7;7852:23;7848:32;7845:52;;;7893:1;7890;7883:12;7845:52;7925:9;7919:16;7944:28;7966:5;7944:28;:::i;8007:232::-;8046:3;8067:17;;;8064:140;;8126:10;8121:3;8117:20;8114:1;8107:31;8161:4;8158:1;8151:15;8189:4;8186:1;8179:15;8064:140;-1:-1:-1;8231:1:137;8220:13;;8007:232::o;8654:648::-;8734:6;8787:2;8775:9;8766:7;8762:23;8758:32;8755:52;;;8803:1;8800;8793:12;8755:52;8836:9;8830:16;8869:18;8861:6;8858:30;8855:50;;;8901:1;8898;8891:12;8855:50;8924:22;;8977:4;8969:13;;8965:27;-1:-1:-1;8955:55:137;;9006:1;9003;8996:12;8955:55;9035:2;9029:9;9060:48;9076:31;9104:2;9076:31;:::i;9060:48::-;9131:2;9124:5;9117:17;9171:7;9166:2;9161;9157;9153:11;9149:20;9146:33;9143:53;;;9192:1;9189;9182:12;9143:53;9205:67;9269:2;9264;9257:5;9253:14;9248:2;9244;9240:11;9205:67;:::i;:::-;9291:5;8654:648;-1:-1:-1;;;;;8654:648:137:o;9307:184::-;9377:6;9430:2;9418:9;9409:7;9405:23;9401:32;9398:52;;;9446:1;9443;9436:12;9398:52;-1:-1:-1;9469:16:137;;9307:184;-1:-1:-1;9307:184:137:o;9496:401::-;9698:2;9680:21;;;9737:2;9717:18;;;9710:30;9776:34;9771:2;9756:18;;9749:62;-1:-1:-1;;;9842:2:137;9827:18;;9820:35;9887:3;9872:19;;9496:401::o;11379:414::-;11581:2;11563:21;;;11620:2;11600:18;;;11593:30;11659:34;11654:2;11639:18;;11632:62;-1:-1:-1;;;11725:2:137;11710:18;;11703:48;11783:3;11768:19;;11379:414::o;11798:489::-;-1:-1:-1;;;;;12067:15:137;;;12049:34;;12119:15;;12114:2;12099:18;;12092:43;12166:2;12151:18;;12144:34;;;12214:3;12209:2;12194:18;;12187:31;;;11992:4;;12235:46;;12261:19;;12253:6;12235:46;:::i;:::-;12227:54;11798:489;-1:-1:-1;;;;;;11798:489:137:o;12292:249::-;12361:6;12414:2;12402:9;12393:7;12389:23;12385:32;12382:52;;;12430:1;12427;12420:12;12382:52;12462:9;12456:16;12481:30;12505:5;12481:30;:::i","linkReferences":{},"immutableReferences":{"68284":[{"start":443,"length":32},{"start":1663,"length":32}]}},"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","burn(uint256)":"42966c68","getApproved(uint256)":"081812fc","getStateFingerprint(uint256)":"f5112315","hub()":"365a86fc","isApprovedForAll(address,address)":"e985e9c5","lastLoanId()":"68be92b4","loanContract(uint256)":"a00d21fc","mint(address)":"6a627842","name()":"06fdde03","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","symbol()":"95d89b41","tokenURI(uint256)":"c87b56dd","transferFrom(address,address,uint256)":"23b872dd"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_hub\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"CallerMissingHubTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLoanContractCaller\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"LOANBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"LOANMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getStateFingerprint\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hub\",\"outputs\":[{\"internalType\":\"contract PWNHub\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastLoanId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"loanContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Token doesn't hold any loan logic, just an address of a loan contract that minted the LOAN token. PWN LOAN token is shared between all loan contracts.\",\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"burn(uint256)\":{\"details\":\"Any address that is associated with given loan id can call this function. It is enabled to let deprecated loan contracts repay and claim existing loans.\",\"params\":{\"loanId\":\"Id of a LOAN token to be burned.\"}},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"getStateFingerprint(uint256)\":{\"details\":\"See {IERC5646-getStateFingerprint}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"mint(address)\":{\"details\":\"Only an address with associated `ACTIVE_LOAN` tag in PWN Hub can call this function.\",\"params\":{\"owner\":\"Address of a LOAN token receiver.\"},\"returns\":{\"loanId\":\"Id of a newly minted LOAN token.\"}},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenURI(uint256)\":{\"params\":{\"tokenId\":\"Id of a LOAN token.\"},\"returns\":{\"_0\":\"Metadata uri for given token id (loan id).\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"stateVariables\":{\"lastLoanId\":{\"details\":\"Last used LOAN id. First LOAN id is 1. This value is incremental.\"},\"loanContract\":{\"details\":\"Mapping of a LOAN id to a loan contract that minted the LOAN token.\"}},\"title\":\"PWN LOAN token\",\"version\":1},\"userdoc\":{\"errors\":{\"CallerMissingHubTag(bytes32)\":[{\"notice\":\"Thrown when caller is missing a PWN Hub tag.\"}],\"InvalidLoanContractCaller()\":[{\"notice\":\"Thrown when `PWNLOAN.burn` caller is not a loan contract that minted the LOAN token.\"}]},\"events\":{\"LOANBurned(uint256)\":{\"notice\":\"Emitted when a LOAN token is burned.\"},\"LOANMinted(uint256,address,address)\":{\"notice\":\"Emitted when a new LOAN token is minted.\"}},\"kind\":\"user\",\"methods\":{\"burn(uint256)\":{\"notice\":\"Burn a LOAN token.\"},\"mint(address)\":{\"notice\":\"Mint a new LOAN token.\"},\"tokenURI(uint256)\":{\"notice\":\"Return a LOAN token metadata uri base on a loan contract that minted the token.\"}},\"notice\":\"A LOAN token representing a loan in PWN protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/loan/token/PWNLOAN.sol\":\"PWNLOAN\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005\",\"dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4\",\"dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]},\"src/hub/PWNHubTags.sol\":{\"keccak256\":\"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8\",\"dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ\"]},\"src/interfaces/IERC5646.sol\":{\"keccak256\":\"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180\",\"dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki\"]},\"src/interfaces/IPWNLoanMetadataProvider.sol\":{\"keccak256\":\"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6\",\"dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK\"]},\"src/loan/token/PWNLOAN.sol\":{\"keccak256\":\"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219\",\"dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_hub","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"tag","type":"bytes32"}],"type":"error","name":"CallerMissingHubTag"},{"inputs":[],"type":"error","name":"InvalidLoanContractCaller"},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"approved","type":"address","indexed":true},{"internalType":"uint256","name":"tokenId","type":"uint256","indexed":true}],"type":"event","name":"Approval","anonymous":false},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"operator","type":"address","indexed":true},{"internalType":"bool","name":"approved","type":"bool","indexed":false}],"type":"event","name":"ApprovalForAll","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true}],"type":"event","name":"LOANBurned","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"address","name":"loanContract","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true}],"type":"event","name":"LOANMinted","anonymous":false},{"inputs":[{"internalType":"address","name":"from","type":"address","indexed":true},{"internalType":"address","name":"to","type":"address","indexed":true},{"internalType":"uint256","name":"tokenId","type":"uint256","indexed":true}],"type":"event","name":"Transfer","anonymous":false},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"approve"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"burn"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getStateFingerprint","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"hub","outputs":[{"internalType":"contract PWNHub","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function","name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"lastLoanId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","name":"loanContract","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"mint","outputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"name","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"safeTransferFrom"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"safeTransferFrom"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setApprovalForAll"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transferFrom"}],"devdoc":{"kind":"dev","methods":{"approve(address,uint256)":{"details":"See {IERC721-approve}."},"balanceOf(address)":{"details":"See {IERC721-balanceOf}."},"burn(uint256)":{"details":"Any address that is associated with given loan id can call this function. It is enabled to let deprecated loan contracts repay and claim existing loans.","params":{"loanId":"Id of a LOAN token to be burned."}},"getApproved(uint256)":{"details":"See {IERC721-getApproved}."},"getStateFingerprint(uint256)":{"details":"See {IERC5646-getStateFingerprint}."},"isApprovedForAll(address,address)":{"details":"See {IERC721-isApprovedForAll}."},"mint(address)":{"details":"Only an address with associated `ACTIVE_LOAN` tag in PWN Hub can call this function.","params":{"owner":"Address of a LOAN token receiver."},"returns":{"loanId":"Id of a newly minted LOAN token."}},"name()":{"details":"See {IERC721Metadata-name}."},"ownerOf(uint256)":{"details":"See {IERC721-ownerOf}."},"safeTransferFrom(address,address,uint256)":{"details":"See {IERC721-safeTransferFrom}."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"See {IERC721-safeTransferFrom}."},"setApprovalForAll(address,bool)":{"details":"See {IERC721-setApprovalForAll}."},"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."},"symbol()":{"details":"See {IERC721Metadata-symbol}."},"tokenURI(uint256)":{"params":{"tokenId":"Id of a LOAN token."},"returns":{"_0":"Metadata uri for given token id (loan id)."}},"transferFrom(address,address,uint256)":{"details":"See {IERC721-transferFrom}."}},"version":1},"userdoc":{"kind":"user","methods":{"burn(uint256)":{"notice":"Burn a LOAN token."},"mint(address)":{"notice":"Mint a new LOAN token."},"tokenURI(uint256)":{"notice":"Return a LOAN token metadata uri base on a loan contract that minted the token."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/loan/token/PWNLOAN.sol":"PWNLOAN"},"evmVersion":"london","libraries":{}},"sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"},"src/hub/PWNHubTags.sol":{"keccak256":"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a","urls":["bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8","dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ"],"license":"GPL-3.0-only"},"src/interfaces/IERC5646.sol":{"keccak256":"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e","urls":["bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180","dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki"],"license":"GPL-3.0-only"},"src/interfaces/IPWNLoanMetadataProvider.sol":{"keccak256":"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8","urls":["bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6","dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK"],"license":"GPL-3.0-only"},"src/loan/token/PWNLOAN.sol":{"keccak256":"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb","urls":["bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219","dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo"],"license":"GPL-3.0-only"}},"version":1},"id":100} \ No newline at end of file diff --git a/packages/subgraph/abis/SimpleLoan.json b/packages/subgraph/abis/SimpleLoan.json new file mode 100644 index 00000000..647d7d6f --- /dev/null +++ b/packages/subgraph/abis/SimpleLoan.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"_hub","type":"address","internalType":"address"},{"name":"_loanToken","type":"address","internalType":"address"},{"name":"_config","type":"address","internalType":"address"},{"name":"_revokedNonce","type":"address","internalType":"address"},{"name":"_categoryRegistry","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"ACCRUING_INTEREST_APR_DECIMALS","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"ACCRUING_INTEREST_APR_DENOMINATOR","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"EXTENSION_PROPOSAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MAX_ACCRUING_INTEREST_APR","inputs":[],"outputs":[{"name":"","type":"uint40","internalType":"uint40"}],"stateMutability":"view"},{"type":"function","name":"MAX_EXTENSION_DURATION","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MINUTES_IN_YEAR","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MIN_EXTENSION_DURATION","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MIN_LOAN_DURATION","inputs":[],"outputs":[{"name":"","type":"uint32","internalType":"uint32"}],"stateMutability":"view"},{"type":"function","name":"VERSION","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"categoryRegistry","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IMultiTokenCategoryRegistry"}],"stateMutability":"view"},{"type":"function","name":"claimLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"config","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNConfig"}],"stateMutability":"view"},{"type":"function","name":"createLOAN","inputs":[{"name":"proposalSpec","type":"tuple","internalType":"struct PWNSimpleLoan.ProposalSpec","components":[{"name":"proposalContract","type":"address","internalType":"address"},{"name":"proposalData","type":"bytes","internalType":"bytes"},{"name":"proposalInclusionProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]},{"name":"lenderSpec","type":"tuple","internalType":"struct PWNSimpleLoan.LenderSpec","components":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]},{"name":"callerSpec","type":"tuple","internalType":"struct PWNSimpleLoan.CallerSpec","components":[{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"revokeNonce","type":"bool","internalType":"bool"},{"name":"nonce","type":"uint256","internalType":"uint256"}]},{"name":"extra","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"extendLOAN","inputs":[{"name":"extension","type":"tuple","internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"extensionProposalsMade","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getExtensionHash","inputs":[{"name":"extension","type":"tuple","internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"status","type":"uint8","internalType":"uint8"},{"name":"startTimestamp","type":"uint40","internalType":"uint40"},{"name":"defaultTimestamp","type":"uint40","internalType":"uint40"},{"name":"borrower","type":"address","internalType":"address"},{"name":"originalLender","type":"address","internalType":"address"},{"name":"loanOwner","type":"address","internalType":"address"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"credit","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"collateral","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"originalSourceOfFunds","type":"address","internalType":"address"},{"name":"repaymentAmount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLenderSpecHash","inputs":[{"name":"lenderSpec","type":"tuple","internalType":"struct PWNSimpleLoan.LenderSpec","components":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"pure"},{"type":"function","name":"getStateFingerprint","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"hub","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNHub"}],"stateMutability":"view"},{"type":"function","name":"isValidAsset","inputs":[{"name":"asset","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"loanMetadataUri","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"loanRepaymentAmount","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"loanToken","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNLOAN"}],"stateMutability":"view"},{"type":"function","name":"makeExtensionProposal","inputs":[{"name":"extension","type":"tuple","internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onERC1155BatchReceived","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256[]","internalType":"uint256[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"pure"},{"type":"function","name":"onERC1155Received","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"type":"function","name":"onERC721Received","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"type":"function","name":"repayLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokedNonce","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNRevokedNonce"}],"stateMutability":"view"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"type":"function","name":"tryClaimRepaidLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"loanOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"ExtensionProposalMade","inputs":[{"name":"extensionHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"proposer","type":"address","indexed":true,"internalType":"address"},{"name":"proposal","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"anonymous":false},{"type":"event","name":"LOANClaimed","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"defaulted","type":"bool","indexed":true,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"LOANCreated","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"proposalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"proposalContract","type":"address","indexed":true,"internalType":"address"},{"name":"refinancingLoanId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"terms","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoan.Terms","components":[{"name":"lender","type":"address","internalType":"address"},{"name":"borrower","type":"address","internalType":"address"},{"name":"duration","type":"uint32","internalType":"uint32"},{"name":"collateral","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"credit","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"lenderSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"borrowerSpecHash","type":"bytes32","internalType":"bytes32"}]},{"name":"lenderSpec","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoan.LenderSpec","components":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]},{"name":"extra","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"LOANExtended","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"originalDefaultTimestamp","type":"uint40","indexed":false,"internalType":"uint40"},{"name":"extendedDefaultTimestamp","type":"uint40","indexed":false,"internalType":"uint40"}],"anonymous":false},{"type":"event","name":"LOANPaidBack","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"PoolSupply","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"poolAdapter","type":"address","indexed":true,"internalType":"address"},{"name":"pool","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"PoolWithdraw","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"poolAdapter","type":"address","indexed":true,"internalType":"address"},{"name":"pool","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultPull","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"origin","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultPush","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"beneficiary","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultPushFrom","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"origin","type":"address","indexed":true,"internalType":"address"},{"name":"beneficiary","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"AddressMissingHubTag","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"CallerNotLOANTokenHolder","inputs":[]},{"type":"error","name":"CallerNotVault","inputs":[]},{"type":"error","name":"Expired","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"expiration","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"IncompleteTransfer","inputs":[]},{"type":"error","name":"InterestAPROutOfBounds","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidDuration","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidExtensionCaller","inputs":[]},{"type":"error","name":"InvalidExtensionDuration","inputs":[{"name":"duration","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidExtensionSigner","inputs":[{"name":"allowed","type":"address","internalType":"address"},{"name":"current","type":"address","internalType":"address"}]},{"type":"error","name":"InvalidLenderSpecHash","inputs":[{"name":"current","type":"bytes32","internalType":"bytes32"},{"name":"expected","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidMultiTokenAsset","inputs":[{"name":"category","type":"uint8","internalType":"uint8"},{"name":"addr","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSignature","inputs":[{"name":"signer","type":"address","internalType":"address"},{"name":"digest","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidSignatureLength","inputs":[{"name":"length","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSourceOfFunds","inputs":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]},{"type":"error","name":"LoanDefaulted","inputs":[{"name":"timestap","type":"uint40","internalType":"uint40"}]},{"type":"error","name":"LoanNotAutoclaimable","inputs":[]},{"type":"error","name":"LoanNotRepaid","inputs":[]},{"type":"error","name":"LoanNotRunning","inputs":[]},{"type":"error","name":"LoanRepaid","inputs":[]},{"type":"error","name":"LoanRunning","inputs":[]},{"type":"error","name":"NonExistingLoan","inputs":[]},{"type":"error","name":"NonceNotUsable","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"RefinanceBorrowerMismatch","inputs":[{"name":"currentBorrower","type":"address","internalType":"address"},{"name":"newBorrower","type":"address","internalType":"address"}]},{"type":"error","name":"RefinanceCollateralMismatch","inputs":[]},{"type":"error","name":"RefinanceCreditMismatch","inputs":[]},{"type":"error","name":"UnsupportedCategory","inputs":[{"name":"categoryValue","type":"uint8","internalType":"uint8"}]},{"type":"error","name":"UnsupportedTransferFunction","inputs":[]},{"type":"error","name":"VaultTransferSameSourceAndDestination","inputs":[{"name":"addr","type":"address","internalType":"address"}]}],"bytecode":{"object":"0x610180604052600361014090815262312e3360e81b610160527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f907f3af43dc47dd092dc79d11f941571a702d1419a15bb1e9b52d0e0e91e22f07352906200006a906101a062000121565b60408051601f1981840301815282825280516020918201209083019490945281019190915260608101919091524660808201523060a082015260c00160408051601f198184030181529190528051602090910120608052348015620000ce57600080fd5b506040516200507838038062005078833981016040819052620000f1916200016f565b60016000556001600160a01b0394851660a05292841660c05290831660e0528216610100521661012052620001df565b6000825160005b8181101562000144576020818601810151858301520162000128565b506000920191825250919050565b80516001600160a01b03811681146200016a57600080fd5b919050565b600080600080600060a086880312156200018857600080fd5b620001938662000152565b9450620001a36020870162000152565b9350620001b36040870162000152565b9250620001c36060870162000152565b9150620001d36080870162000152565b90509295509295909350565b60805160a05160c05160e0516101005161012051614dbd620002bb600039600081816103bd01526113c50152600081816104b50152818161098201528181610cc2015261161a0152600081816104530152818161074901528181611a74015281816126f6015281816127a9015281816128f801528181612aac01526133de01526000818161022d015281816105fe01528181610a990152818161108b015281816112dd015281816124940152818161286e0152612c5501526000818161033101526114ca01526000818161030a01526113ed0152614dbd6000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063706048df1161011a5780639788ad55116100ad578063c399e17d1161007c578063c399e17d146104fa578063c81980801461051a578063f23a6e611461052d578063f511231514610540578063ffa1ad741461055357600080fd5b80639788ad55146104b057806397b090ea146104d75780639e8f9540146104df578063bc197c81146104e757600080fd5b806379502c55116100e957806379502c551461044e5780637f24133f1461047557806389d99a051461047f57806394aedc2f1461049d57600080fd5b8063706048df146104025780637122192c1461041557806374baf6ef14610428578063764d77131461043b57600080fd5b80632c8ebec8116101925780633e6df512116101615780633e6df512146103665780634acacdda1461039157806358099d96146103b8578063640d16ed146103df57600080fd5b80632c8ebec8146102fb5780633644e51514610305578063365a86fc1461032c578063376af4d11461035357600080fd5b8063111d8a15116101ce578063111d8a1514610294578063150b7a02146102a95780631742123c146102d55780632c3eae8a146102e857600080fd5b806301ffc9a71461020057806306d37817146102285780630eb6f582146102675780630ee1ba171461027f575b600080fd5b61021361020e36600461405b565b610575565b60405190151581526020015b60405180910390f35b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161021f565b6102716208052081565b60405190815260200161021f565b61029261028d366004614085565b6105c7565b005b61029c610731565b60405161021f91906140ee565b6102bc6102b7366004614157565b6107c5565b6040516001600160e01b0319909116815260200161021f565b6102926102e33660046141e2565b610803565b6102716102f6366004614085565b610e91565b6102716276a70081565b6102717f000000000000000000000000000000000000000000000000000000000000000081565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610292610361366004614237565b610ed2565b610379610374366004614085565b610faf565b60405161021f9c9b9a999897969594939291906142b4565b6102717f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa71781565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102136103ed366004614085565b60026020526000908152604090205460ff1681565b610292610410366004614085565b6111c8565b610213610423366004614392565b6113bd565b610271610436366004614237565b6113e9565b610271610449366004614418565b6114b6565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102716201518081565b61048861025881565b60405163ffffffff909116815260200161021f565b6102926104ab3660046144a8565b611939565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610271611b2b565b610271606481565b6102bc6104f5366004614525565b611b47565b61050462f4240081565b60405164ffffffffff909116815260200161021f565b6102716105283660046145e3565b611b62565b6102bc61053b3660046145ff565b611b75565b61027161054e366004614085565b611bb3565b61029c60405180604001604052806003815260200162312e3360e81b81525081565b60006001600160e01b031982166301ffc9a760e01b14806105a657506001600160e01b03198216630a85bd0160e11b145b806105c157506001600160e01b03198216630271189760e51b145b92915050565b6105cf611c48565b6000818152600160205260409081902090516331a9108f60e11b81526004810183905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015610645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106699190614685565b6001600160a01b03161461069057604051632a0a3d8160e11b815260040160405180910390fd5b805460ff166000036106b5576040516335cee39560e01b815260040160405180910390fd5b805460ff166003036106d2576106cd82336000611ca1565b610723565b805460ff1660021480156106f95750600181015442600160c81b90910464ffffffffff1611155b1561070a576106cd82336001611ca1565b6040516311d01f2b60e31b815260040160405180910390fd5b5061072e6001600055565b50565b604051630233557560e41b81523060048201526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632335575090602401600060405180830381865afa158015610798573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107c091908101906146a2565b905090565b60006001600160a01b03861630146107f0576040516382a1dea160e01b815260040160405180910390fd5b50630a85bd0160e11b5b95945050505050565b61080b611c48565b823560009081526001602052604081208054909160ff9091169003610843576040516335cee39560e01b815260040160405180910390fd5b805460ff1660030361086857604051631062e18f60e01b815260040160405180910390fd5b6000610873856113e9565b60008181526002602052604090205490915060ff16610921576108dc61089f60c0870160a08801614743565b8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d8d92505050565b610921576108f060c0860160a08701614743565b6040516301d2d55760e31b81526001600160a01b039091166004820152602481018290526044015b60405180910390fd5b61093160a0860160808701614775565b64ffffffffff164210610978574261094f60a0870160808801614775565b60405163aa2fd92560e01b8152600481019290925264ffffffffff166024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f291a62c6109b760c0880160a08901614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08901356024820152908801356044820152606401602060405180830381865afa158015610a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a33919061479e565b610a8057610a4760c0860160a08701614743565b604051632108c30560e11b81526001600160a01b03909116600482015260c0860135602482015260e08601356044820152606401610918565b6040516331a9108f60e11b8152853560048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0c9190614685565b90506001600160a01b0381163303610b985760028301546001600160a01b0316610b3c60c0880160a08901614743565b6001600160a01b031614610b935760028301546001600160a01b0316610b6860c0880160a08901614743565b604051627c5e8760e31b81526001600160a01b03928316600482015291166024820152604401610918565b610bfe565b60028301546001600160a01b03163303610be5576001600160a01b038116610bc660c0880160a08901614743565b6001600160a01b031614610b935780610b6860c0880160a08901614743565b604051639d29f3a960e01b815260040160405180910390fd5b62015180610c126080880160608901614775565b64ffffffffff161015610c5b57610c2f6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff9091166004820152620151806024820152604401610918565b6276a700610c6f6080880160608901614775565b64ffffffffff161115610cb857610c8c6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff90911660048201526276a7006024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f79924a9610cf760c0890160a08a01614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08a01356024820152908901356044820152606401600060405180830381600087803b158015610d4c57600080fd5b505af1158015610d60573d6000803e3d6000fd5b505050506001830154600160c81b900464ffffffffff16610d876080880160608901614775565b610d9190826147d1565b60018501805464ffffffffff60c81b1916600160c81b64ffffffffff938416810291909117918290556040805185851681529190920490921660208301528835917f16e70f82a9a68fdbf6cc67068dcfadcaf1e0c61409aa3a24122767789ccc20d5910160405180910390a26000610e0f6040890160208a01614743565b6001600160a01b031614158015610e2a575060008760400135115b15610e7e576000610e5760408901803590610e489060208c01614743565b6001600160a01b031690611f33565b9050610e6281611f6b565b6002850154610e7c9082906001600160a01b031685611fd6565b505b50505050610e8c6001600055565b505050565b6000818152600160205260408120805460ff168203610eb35750600092915050565b610ebc8161204e565b8160050154610ecb91906147f6565b9392505050565b610ee260c0820160a08301614743565b6001600160a01b0316336001600160a01b031614610f3457610f0a60c0820160a08301614743565b604051627c5e8760e31b81526001600160a01b039091166004820152336024820152604401610918565b6000610f3f826113e9565b6000818152600260205260409020805460ff191660011790559050610f6a60c0830160a08401614743565b6001600160a01b0316817f3404b1a797c8c84bf93d13290f9f6e7464634602778a1ffa1fc7d8708668022e84604051610fa39190614809565b60405180910390a35050565b600080600080600080600080610fc3614029565b610fcb614029565b60008b81526001602052604081208190610fe48e612101565b9c508060010160149054906101000a900464ffffffffff169b508060010160199054906101000a900464ffffffffff169a508060020160009054906101000a90046001600160a01b031699508060030160009054906101000a90046001600160a01b031698508060000160009054906101000a900460ff1660ff1660000361106d5760006110f6565b6040516331a9108f60e11b8152600481018f90526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f69190614685565b6003820154600483015460058401548454939b50600160a01b90920462ffffff16995097506111339161010090046001600160a01b031690611f33565b60408051608081019091526006830180549297509091829060ff16600381111561115f5761115f614254565b600381111561117057611170614254565b815281546001600160a01b03610100909104811660208301526001808401546040840152600290930154606090920191909152908301549195501692506111b68e610e91565b91505091939597999b5091939597999b565b6111d0611c48565b600081815260016020819052604090912080549181015490916112069160ff90911690600160c81b900464ffffffffff1661214d565b61120f826121c9565b600061121a83610e91565b82549091506112419061123b9061010090046001600160a01b031683611f33565b33612230565b60408051608081019091526006830180546112bb929190829060ff16600381111561126e5761126e614254565b600381111561127f5761127f614254565b815281546001600160a01b036101009091048116602083015260018301546040830152600292830154606090920191909152908501541661229d565b6040516331a9108f60e11b81526004810184905230906394aedc2f90859084907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa15801561132c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113509190614685565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526001600160a01b03166044820152606401600060405180830381600087803b15801561139f57600080fd5b505af19250505080156113b0575060015b50505061072e6001600055565b60006105c1827f00000000000000000000000000000000000000000000000000000000000000006122fd565b60007f00000000000000000000000000000000000000000000000000000000000000007f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa7178360405160200161143e9190614809565b60408051601f198184030181529082905261145c929160200161489f565b6040516020818303038152906040528051906020012060405160200161149992919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b60006114c0611c48565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d019577a6114fc6020890189614743565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401602060405180830381865afa158015611566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158a919061479e565b6115e65761159b6020870187614743565b604051630b92eb2560e11b81526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401610918565b6115f660408501602086016148c5565b1561167f5760408051630a69412f60e21b81523360048201529085013560248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906329a504bc90604401600060405180830381600087803b15801561166657600080fd5b505af115801561167a573d6000803e3d6000fd5b505050505b8335156116ca578335600090815260016020819052604090912080549181015490916116be9160ff90911690600160c81b900464ffffffffff1661214d565b6116c885356121c9565b505b6000806116da6020890189614743565b6001600160a01b03166301e832723388356116f860208d018d6148e2565b61170560408f018f614928565b8f806060019061171591906148e2565b6040518963ffffffff1660e01b815260040161173898979695949392919061499a565b610200604051808303816000875af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190614ab6565b805191935091506001600160a01b031633148015906117a7575061179f87611b62565b8160e0015114155b156117dc578060e001516117ba88611b62565b604051633188f56d60e11b815260048101929092526024820152604401610918565b61025863ffffffff16816040015163ffffffff16101561182557604080820151905163387a058b60e01b815263ffffffff90911660048201526102586024820152604401610918565b62f4240064ffffffffff168160c0015162ffffff16111561186f5760c0810151604051630fb8adc560e41b815262ffffff909116600482015262f424006024820152604401610918565b8535600003611897576118858160800151611f6b565b6118928160600151611f6b565b6118a2565b6118a2863582612319565b6118ac8188612470565b92506118bb6020890189614743565b6001600160a01b031682847f81757c17b6937fd2ab5739a2842fe6165ef6bee2d0b24179f95fbf761634a68a8960000135858c8b8b604051611901959493929190614b96565b60405180910390a485356000036119215761191c81886126a7565b61192d565b61192d86358289612847565b50506107fa6001600055565b3330146119595760405163edd7338f60e01b815260040160405180910390fd5b6000838152600160205260409020805460ff1660031461198b57604051625bdcbf60e11b815260040160405180910390fd5b60038101546001600160a01b038381169116146119bb5760405163499174ef60e01b815260040160405180910390fd5b600181015481546001600160a01b03918216916000916119e2916101009091041686611f33565b90506119ed86612c3f565b60405160009087907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b73908390a384600003611a2a57505050505050565b836001600160a01b0316826001600160a01b031603611a5257611a4d818561229d565b611b23565b60405163b209123160e01b81526001600160a01b0383811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063b209123190602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190614685565b90506001600160a01b038116611b1557604051632f9526c360e11b81526001600160a01b0384166004820152602401610918565b611b2182828588612d35565b505b505050505050565b611b39620805206064614c5a565b611b44906064614c5a565b81565b60006040516382a1dea160e01b815260040160405180910390fd5b6000816040516020016114999190614c79565b60006001600160a01b0387163014611ba0576040516382a1dea160e01b815260040160405180910390fd5b5063f23a6e6160e01b9695505050505050565b6000818152600160205260408120805460ff168203611bd55750600092915050565b611bde83612101565b6001820154600483015460038401546040805160ff9095166020860152600160c81b90930464ffffffffff16928401929092526060830152600160a01b900462ffffff16608082015260a00160405160208183030381529060405280519060200120915050919050565b600260005403611c9a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610918565b6002600055565b60008381526001602052604081209082611cdc57611cd7611cc186610e91565b835461010090046001600160a01b031690611f33565b611d42565b6040805160808101909152600683018054829060ff166003811115611d0357611d03614254565b6003811115611d1457611d14614254565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546060909101525b9050611d4d85612c3f565b6040518315159086907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b7390600090a3611d86818561229d565b5050505050565b60006001600160a01b0384163b15611e8857600080856001600160a01b0316631626ba7e60e01b8686604051602401611dc7929190614c99565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611e059190614cb2565b600060405180830381855afa9150503d8060008114611e40576040519150601f19603f3d011682016040523d82523d6000602084013e611e45565b606091505b5091509150818015611e58575080516020145b8015611e7f57508051630b135d3f60e11b90611e7d9083016020908101908401614cce565b145b92505050610ecb565b60008060008451604103611eb05750505060208201516040830151606084015160001a611f07565b8451604003611ee957602085015160408601519093506001600160ff1b0381169250611ee160ff82901c601b6147f6565b915050611f07565b845160405163058676ad60e31b815260040161091891815260200190565b611f1386828585612e36565b6001600160a01b0316876001600160a01b03161493505050509392505050565b611f3b614029565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b611f74816113bd565b61072e5780516003811115611f8b57611f8b614254565b60208201516040808401516060850151915163032163e160e11b815260ff90941660048501526001600160a01b03909216602484015260448301919091526064820152608401610918565b6000611fe28483612e5e565b9050611fef8484846130a8565b611ffd8482848660016130b5565b816001600160a01b0316836001600160a01b03167f0272ef83f5953daad3d7708e6b4442e126f1e049e62a01c1fc53683f3277199c866040516120409190614ce7565b60405180910390a350505050565b6003810154600090600160a01b900462ffffff16810361207057506004015490565b6001820154600090603c9061209390600160a01b900464ffffffffff1642614cf5565b61209d9190614d1e565b600584015460038501549192506000916120e791906120c9908590600160a01b900462ffffff16614c5a565b6120d7620805206064614c5a565b6120e2906064614c5a565b61314f565b90508084600401546120f991906147f6565b949350505050565b6000818152600160205260408120805460ff1660021480156121365750600181015442600160c81b90910464ffffffffff1611155b61214457805460ff16610ecb565b60049392505050565b8160ff16600003612171576040516335cee39560e01b815260040160405180910390fd5b8160ff16600214612195576040516331fe4d5d60e01b815260040160405180910390fd5b428164ffffffffff16116121c557604051631e3cd61560e01b815264ffffffffff82166004820152602401610918565b5050565b6000818152600160205260409020805460ff191660031781556121eb8161204e565b600482015560038101805462ffffff60a01b1916905560405182907ff1e5b832ef53e7d611651983b38ff941f4d2049e9c8962c623c2664bca312bc090600090a25050565b600061223c8330612e5e565b9050612249838330613239565b6122578382308560016130b5565b816001600160a01b03167f019fcaae912e42069954835069f1c8184411022f86cf749694625f2a2313b6ab846040516122909190614ce7565b60405180910390a2505050565b60006122a98383612e5e565b90506122b68330846130a8565b6122c48382843060016130b5565b816001600160a01b03167fc2b8da69776ffa72ca2d7c4a31390d57bd4871cef8066bbe7f1e5bf220a310f1846040516122909190614ce7565b60006123098383613246565b8015610ecb5750610ecb836132f4565b6000828152600160209081526040909120608083015190910151815461010090046001600160a01b03908116911614158061235a5750608082015160600151155b1561237857604051635f860c6160e11b815260040160405180910390fd5b606082015151600381111561238f5761238f614254565b600682015460ff1660038111156123a8576123a8614254565b1415806123d35750606082015160200151600682015461010090046001600160a01b03908116911614155b806123ea5750606082015160400151600782015414155b8061240057506060808301510151600882015414155b1561241e5760405163175bb1b760e21b815260040160405180910390fd5b602082015160028201546001600160a01b03908116911614610e8c576002810154602083015160405163d4b919f760e01b81526001600160a01b03928316600482015291166024820152604401610918565b81516040516335313c2160e11b81526001600160a01b0391821660048201526000917f00000000000000000000000000000000000000000000000000000000000000001690636a627842906024016020604051808303816000875af11580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190614cce565b6000818152600160209081526040909120805460808701518301516001600160a01b0316610100026001600160a81b031990911617600217815591925061254a90840184614743565b60018201805464ffffffffff42908116600160a01b026001600160c81b03199092166001600160a01b03949094169390931717905560408501516125969163ffffffff909116906147d1565b6001808301805464ffffffffff93909316600160c81b0264ffffffffff60c81b199093169290921790915560208501516002830180546001600160a01b039283166001600160a01b031990911617905585516003808501805460c08a015162ffffff16600160a01b026001600160b81b0319909116939094169290921792909217905560a08601516004840155608086015160609081015160058501558601518051600685018054929490939192849260ff199091169190849081111561265f5761265f614254565b0217905550602082015181546001600160a01b0390911661010002610100600160a81b0319909116178155604082015160018201556060909101516002909101555092915050565b6126b982606001518360200151612230565b81516001600160a01b03166126d16020830183614743565b6001600160a01b0316146126ee576126ee826080015183836133d2565b6000806127847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127769190614d40565b8560800151606001516134e3565b60808601519193509150821561282e578281606001818152505061282e8186600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128299190614685565b611fd6565b6060810182905284516020860151611d86918391611fd6565b60008381526001602052604080822090516331a9108f60e11b8152600481018690529091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156128bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e19190614685565b905060006128ee86610e91565b90506000806129867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612954573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129789190614d40565b8860800151606001516134e3565b9150915060006129968483613524565b905060008483116129a85760006129b2565b6129b28584614cf5565b905060008082116129cc576129c78487614cf5565b6129cf565b60005b90506000876001600160a01b03168b600001516001600160a01b0316141580612a2f575060038901546001600160a01b038981169116148015612a2f5750612a1a60208b018b614743565b60018a01546001600160a01b03908116911614155b60808c01518c51919250906001600160a01b0316612a5060208d018d614743565b6001600160a01b031614612a91578382612a6b576000612a6d565b855b612a7790896147f6565b612a8191906147f6565b6060820152612a91818d8d6133d2565b8615612b085786816060018181525050612b08818d600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b8115612b2257606081018590528b51612b22908290612230565b8315612b4657606081018490528b5160208d0151612b41918391611fd6565b612b63565b8215612b63576060810183905260208c0151612b63908290612230565b306394aedc2f8e8585612b77576000612b79565b885b612b8391906147f6565b6040516001600160e01b031960e085901b168152600481019290925260248201526001600160a01b038c166044820152606401600060405180830381600087803b158015612bd057600080fd5b505af1925050508015612be1575060015b612c305781612c3057606081018590528b516001600160a01b0316612c0960208d018d614743565b6001600160a01b031614612c2257612c22818d8d6133d2565b612c30818d60000151612230565b50505050505050505050505050565b604051630852cd8d60e31b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b158015612ca157600080fd5b505af1158015612cb5573d6000803e3d6000fd5b505050600091825250600160208190526040822080546001600160a81b0319908116825591810180546001600160f01b03191690556002810180546001600160a01b03191690556003810180546001600160b81b031916905560048101839055600581018390556006810180549092169091556007810182905560080155565b6000612d418530612e5e565b9050612d4e853086613239565b6020850151606086015160405163107c8ed760e01b81526001600160a01b0386811660048301528581166024830152928316604482015260648101919091529085169063107c8ed790608401600060405180830381600087803b158015612db457600080fd5b505af1158015612dc8573d6000803e3d6000fd5b50505050612dda8582308660006130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167fb58f4e60b4600784c073e07e7bb67825fe64b4592b5c7ce254599a9b8dcc4d8288604051612e279190614ce7565b60405180910390a45050505050565b6000806000612e478787878761353a565b91509150612e54816135fe565b5095945050505050565b60008083516003811115612e7457612e74614254565b03612ef15760208301516040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024015b602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190614cce565b90506105c1565b600183516003811115612f0657612f06614254565b03612fae57816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b602060405180830381865afa158015612f68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8c9190614685565b6001600160a01b031614612fa1576000612fa4565b60015b60ff1690506105c1565b600283516003811115612fc357612fc3614254565b036130065760208301516040808501519051627eeac760e11b81526001600160a01b038581166004830152602482019290925291169062fdd58e90604401612ea9565b60038351600381111561301b5761301b614254565b0361306057816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b60405162461bcd60e51b815260206004820181905260248201527f4d756c7469546f6b656e3a20556e737570706f727465642063617465676f72796044820152606401610918565b610e8c8383836001613748565b816001600160a01b0316836001600160a01b0316036130f25760405163bb77337360e01b81526001600160a01b0384166004820152602401610918565b6000816131115761310286613a01565b61310c9086614cf5565b613124565b61311a86613a01565b61312490866147f6565b90506131308685612e5e565b8114611b23576040516345ffc53d60e11b815260040160405180910390fd5b60008080600019858709858702925082811083820303915050806000036131895783828161317f5761317f614d08565b0492505050610ecb565b8084116131d05760405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606401610918565b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b610e8c8383836000613748565b6020820151604051638481ab0760e01b81526001600160a01b039182166004820152600091829190841690638481ab0790602401602060405180830381865afa158015613297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bb9190614d64565b905060ff808216146132eb57835160ff82169060038111156132df576132df614254565b60ff16149150506105c1565b6120f984613a5c565b6000808251600381111561330a5761330a614254565b036133265760408201511561332157506000919050565b6133ca565b60018251600381111561333b5761333b614254565b036133525760608201511561332157506000919050565b60028251600381111561336757613367614254565b146133ca5760038251600381111561338157613381614254565b036133985760608201511561332157506000919050565b815160038111156133ab576133ab614254565b604051635928f9a360e11b815260ff9091166004820152602401610918565b506001919050565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b20912316134106020850185614743565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015613454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134789190614685565b90506001600160a01b0381166134ba576134956020830183614743565b604051632f9526c360e11b81526001600160a01b039091166004820152602401610918565b6060840151156134dd576134dd84826134d66020860186614743565b8651613bf2565b50505050565b6000808361ffff166000036134fd5750600090508161351d565b61350e838561ffff1661271061314f565b915061351a8284614cf5565b90505b9250929050565b60008183106135335781610ecb565b5090919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561357157506000905060036135f5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135c5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ee576000600192509250506135f5565b9150600090505b94509492505050565b600081600481111561361257613612614254565b0361361a5750565b600181600481111561362e5761362e614254565b0361367b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610918565b600281600481111561368f5761368f614254565b036136dc5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610918565b60038160048111156136f0576136f0614254565b0361072e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610918565b60008451600381111561375d5761375d614254565b036137c557306001600160a01b0384160361379d5761379882856060015186602001516001600160a01b0316613cd99092919063ffffffff16565b6134dd565b6137988383866060015187602001516001600160a01b0316613d3c909392919063ffffffff16565b6001845160038111156137da576137da614254565b036138b5578061385f57602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd906064015b600060405180830381600087803b15801561384257600080fd5b505af1158015613856573d6000803e3d6000fd5b505050506134dd565b60208401516040808601519051635c46a7ef60e11b81526001600160a01b03868116600483015285811660248301526044820192909252608060648201526000608482015291169063b88d4fde9060a401613828565b6002845160038111156138ca576138ca614254565b0361394f5783602001516001600160a01b031663f242432a8484876040015188606001516000146138ff578860600151613902565b60015b6040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260a06084820152600060a482015260c401613828565b60038451600381111561396457613964614254565b0361306057306001600160a01b038416036139b9576020840151604080860151905163a9059cbb60e01b81526001600160a01b038581166004830152602482019290925291169063a9059cbb90604401613828565b602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd90606401613828565b60008082516003811115613a1757613a17614254565b03613a2457506060015190565b600282516003811115613a3957613a39614254565b148015613a4a575060008260600151115b156133ca57506060015190565b919050565b60008082516003811115613a7257613a72614254565b03613b4757613a8d82602001516001600160a01b0316613d74565b15613b33576020820151613ab1906001600160a01b03166336372b0760e01b613d9c565b15613abe57506001919050565b6020820151613add906001600160a01b03166380ac58cd60e01b613d9c565b158015613b0657506020820151613b04906001600160a01b0316636cdb3d1360e11b613d9c565b155b80156105c157506020820151613b2c906001600160a01b0316639a20483d60e01b613d9c565b1592915050565b50602001516001600160a01b03163b151590565b600182516003811115613b5c57613b5c614254565b03613b805760208201516105c1906001600160a01b03166380ac58cd60e01b613e25565b600282516003811115613b9557613b95614254565b03613bb95760208201516105c1906001600160a01b0316636cdb3d1360e11b613e25565b600382516003811115613bce57613bce614254565b036133985760208201516105c1906001600160a01b0316639a20483d60e01b613e25565b6000613bfe8583612e5e565b60208601516060870151604051630b620b8160e01b81526001600160a01b038781166004830152868116602483015292831660448201526064810191909152919250851690630b620b8190608401600060405180830381600087803b158015613c6657600080fd5b505af1158015613c7a573d6000803e3d6000fd5b50505050613c8c8582848660016130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167f4c6641e50ab591b51c5b75ab0d3721eb0357eac106223e5d21b1ceb5c2abd30388604051612e279190614ce7565b6040516001600160a01b038316602482015260448101829052610e8c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613e41565b6040516001600160a01b03808516602483015283166044820152606481018290526134dd9085906323b872dd60e01b90608401613d05565b6000613d87826301ffc9a760e01b613d9c565b80156105c15750613b2c826001600160e01b03195b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015613e0e575060208210155b8015613e1a5750600081115b979650505050505050565b6000613e3083613d74565b8015610ecb5750610ecb8383613d9c565b6000613e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f169092919063ffffffff16565b9050805160001480613eb7575080806020019051810190613eb7919061479e565b610e8c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610918565b60606120f9848460008585600080866001600160a01b03168587604051613f3d9190614cb2565b60006040518083038185875af1925050503d8060008114613f7a576040519150601f19603f3d011682016040523d82523d6000602084013e613f7f565b606091505b5091509150613e1a8783838760608315613ffa578251600003613ff3576001600160a01b0385163b613ff35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610918565b50816120f9565b6120f9838381511561400f5781518083602001fd5b8060405162461bcd60e51b815260040161091891906140ee565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b60006020828403121561406d57600080fd5b81356001600160e01b031981168114610ecb57600080fd5b60006020828403121561409757600080fd5b5035919050565b60005b838110156140b95781810151838201526020016140a1565b50506000910152565b600081518084526140da81602086016020860161409e565b601f01601f19169290920160200192915050565b602081526000610ecb60208301846140c2565b6001600160a01b038116811461072e57600080fd5b60008083601f84011261412857600080fd5b5081356001600160401b0381111561413f57600080fd5b60208301915083602082850101111561351d57600080fd5b60008060008060006080868803121561416f57600080fd5b853561417a81614101565b9450602086013561418a81614101565b93506040860135925060608601356001600160401b038111156141ac57600080fd5b6141b888828901614116565b969995985093965092949392505050565b600061010082840312156141dc57600080fd5b50919050565b600080600061012084860312156141f857600080fd5b61420285856141c9565b92506101008401356001600160401b0381111561421e57600080fd5b61422a86828701614116565b9497909650939450505050565b6000610100828403121561424a57600080fd5b610ecb83836141c9565b634e487b7160e01b600052602160045260246000fd5b80516004811061428a57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b03169083015260408082015190830152606090810151910152565b60ff8d16815264ffffffffff8c811660208301528b1660408201526001600160a01b038a811660608301528981166080830152881660a082015262ffffff871660c082015260e08101869052610240810161431361010083018761426a565b61432161018083018661426a565b6001600160a01b039390931661020082015261022001529a9950505050505050505050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561437f5761437f614346565b60405290565b6004811061072e57600080fd5b6000608082840312156143a457600080fd5b604051608081018181106001600160401b03821117156143c6576143c6614346565b60405282356143d481614385565b815260208301356143e481614101565b6020820152604083810135908201526060928301359281019290925250919050565b6000602082840312156141dc57600080fd5b600080600080600085870360c081121561443157600080fd5b86356001600160401b038082111561444857600080fd5b908801906080828b03121561445c57600080fd5b81975061446c8a60208b01614406565b96506060603f198401121561448057600080fd5b60408901955060a089013592508083111561449a57600080fd5b50506141b888828901614116565b6000806000606084860312156144bd57600080fd5b833592506020840135915060408401356144d681614101565b809150509250925092565b60008083601f8401126144f357600080fd5b5081356001600160401b0381111561450a57600080fd5b6020830191508360208260051b850101111561351d57600080fd5b60008060008060008060008060a0898b03121561454157600080fd5b883561454c81614101565b9750602089013561455c81614101565b965060408901356001600160401b038082111561457857600080fd5b6145848c838d016144e1565b909850965060608b013591508082111561459d57600080fd5b6145a98c838d016144e1565b909650945060808b01359150808211156145c257600080fd5b506145cf8b828c01614116565b999c989b5096995094979396929594505050565b6000602082840312156145f557600080fd5b610ecb8383614406565b60008060008060008060a0878903121561461857600080fd5b863561462381614101565b9550602087013561463381614101565b9450604087013593506060870135925060808701356001600160401b0381111561465c57600080fd5b61466889828a01614116565b979a9699509497509295939492505050565b8051613a5781614101565b60006020828403121561469757600080fd5b8151610ecb81614101565b6000602082840312156146b457600080fd5b81516001600160401b03808211156146cb57600080fd5b818401915084601f8301126146df57600080fd5b8151818111156146f1576146f1614346565b604051601f8201601f19908116603f0116810190838211818310171561471957614719614346565b8160405282815287602084870101111561473257600080fd5b613e1a83602083016020880161409e565b60006020828403121561475557600080fd5b8135610ecb81614101565b803564ffffffffff81168114613a5757600080fd5b60006020828403121561478757600080fd5b610ecb82614760565b801515811461072e57600080fd5b6000602082840312156147b057600080fd5b8151610ecb81614790565b634e487b7160e01b600052601160045260246000fd5b64ffffffffff8181168382160190808211156147ef576147ef6147bb565b5092915050565b808201808211156105c1576105c16147bb565b813581526101008101602083013561482081614101565b6001600160a01b031660208301526040838101359083015261484460608401614760565b64ffffffffff80821660608501528061485f60808701614760565b166080850152505060a083013561487581614101565b6001600160a01b03811660a08401525060c083013560c083015260e083013560e083015292915050565b828152600082516148b781602085016020870161409e565b919091016020019392505050565b6000602082840312156148d757600080fd5b8135610ecb81614790565b6000808335601e198436030181126148f957600080fd5b8301803591506001600160401b0382111561491357600080fd5b60200191503681900382131561351d57600080fd5b6000808335601e1984360301811261493f57600080fd5b8301803591506001600160401b0382111561495957600080fd5b6020019150600581901b360382131561351d57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038916815287602082015260a0604082015260006149c260a08301888a614971565b82810360608401528581526001600160fb1b038611156149e157600080fd5b8560051b808860208401370182810360209081016080850152614a079082018587614971565b9b9a5050505050505050505050565b805163ffffffff81168114613a5757600080fd5b600060808284031215614a3c57600080fd5b604051608081018181106001600160401b0382111715614a5e57614a5e614346565b80604052508091508251614a7181614385565b81526020830151614a8181614101565b8060208301525060408301516040820152606083015160608201525092915050565b805162ffffff81168114613a5757600080fd5b600080828403610200811215614acb57600080fd5b835192506101e080601f1983011215614ae357600080fd5b614aeb61435c565b9150614af96020860161467a565b8252614b076040860161467a565b6020830152614b1860608601614a16565b6040830152614b2a8660808701614a2a565b6060830152610100614b3e87828801614a2a565b608084015261018086015160a0840152614b5b6101a08701614aa3565b60c08401526101c086015160e0840152940151938101939093525092909150565b8035614b8781614101565b6001600160a01b031690915250565b85815284516001600160a01b03166020820152600061024060208701516001600160a01b038116604085015250604087015163ffffffff81166060850152506060870151614be7608085018261426a565b506080870151610100614bfc8186018361426a565b60a089015161018086015260c089015162ffffff166101a086015260e08901516101c08601528801516101e085015250614c3a610200840187614b7c565b80610220840152614c4e8184018587614971565b98975050505050505050565b6000816000190483118215151615614c7457614c746147bb565b500290565b602081018235614c8881614101565b6001600160a01b0316909152919050565b8281526040602082015260006120f960408301846140c2565b60008251614cc481846020870161409e565b9190910192915050565b600060208284031215614ce057600080fd5b5051919050565b608081016105c1828461426a565b818103818111156105c1576105c16147bb565b634e487b7160e01b600052601260045260246000fd5b600082614d3b57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215614d5257600080fd5b815161ffff81168114610ecb57600080fd5b600060208284031215614d7657600080fd5b815160ff81168114610ecb57600080fdfea2646970667358221220825b2223fc99b9fa96f255726855d28b700266f4ef852c01cd8fe06f1662a89d64736f6c63430008100033","sourceMap":"2794:7:93:-:0;1359:46454;2794:7;;1359:46454;2794:7;;;-1:-1:-1;;;2794:7:93;;2626:95;;2731:26;;2777:25;;;;:::i;:::-;;;;-1:-1:-1;;2777:25:93;;;;;;;;;2767:36;;2777:25;2767:36;;;;2606:249;;;692:25:137;;;;733:18;;726:34;;;;776:18;;;769:34;;;;2813:13:93;819:18:137;;;812:34;2844:4:93;862:19:137;;;855:61;664:19;;2606:249:93;;;-1:-1:-1;;2606:249:93;;;;;;;;;2596:260;;2606:249;2596:260;;;;2552:304;;12670:402;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1716:1:46;1821:7;:22;-1:-1:-1;;;;;12839:18:93;;;;;12867:31;;;;;12908:27;;;;;12945:45;;;;13000:65;;;1359:46454;;14:414:137;145:3;183:6;177:13;208:1;218:129;232:6;229:1;226:13;218:129;;;330:4;314:14;;;310:25;;304:32;291:11;;;284:53;247:12;218:129;;;-1:-1:-1;402:1:137;366:16;;391:13;;;-1:-1:-1;366:16:137;14:414;-1:-1:-1;14:414:137:o;927:177::-;1006:13;;-1:-1:-1;;;;;1048:31:137;;1038:42;;1028:70;;1094:1;1091;1084:12;1028:70;927:177;;;:::o;1109:550::-;1215:6;1223;1231;1239;1247;1300:3;1288:9;1279:7;1275:23;1271:33;1268:53;;;1317:1;1314;1307:12;1268:53;1340:40;1370:9;1340:40;:::i;:::-;1330:50;;1399:49;1444:2;1433:9;1429:18;1399:49;:::i;:::-;1389:59;;1467:49;1512:2;1501:9;1497:18;1467:49;:::i;:::-;1457:59;;1535:49;1580:2;1569:9;1565:18;1535:49;:::i;:::-;1525:59;;1603:50;1648:3;1637:9;1633:19;1603:50;:::i;:::-;1593:60;;1109:550;;;;;;;;:::o;:::-;1359:46454:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063706048df1161011a5780639788ad55116100ad578063c399e17d1161007c578063c399e17d146104fa578063c81980801461051a578063f23a6e611461052d578063f511231514610540578063ffa1ad741461055357600080fd5b80639788ad55146104b057806397b090ea146104d75780639e8f9540146104df578063bc197c81146104e757600080fd5b806379502c55116100e957806379502c551461044e5780637f24133f1461047557806389d99a051461047f57806394aedc2f1461049d57600080fd5b8063706048df146104025780637122192c1461041557806374baf6ef14610428578063764d77131461043b57600080fd5b80632c8ebec8116101925780633e6df512116101615780633e6df512146103665780634acacdda1461039157806358099d96146103b8578063640d16ed146103df57600080fd5b80632c8ebec8146102fb5780633644e51514610305578063365a86fc1461032c578063376af4d11461035357600080fd5b8063111d8a15116101ce578063111d8a1514610294578063150b7a02146102a95780631742123c146102d55780632c3eae8a146102e857600080fd5b806301ffc9a71461020057806306d37817146102285780630eb6f582146102675780630ee1ba171461027f575b600080fd5b61021361020e36600461405b565b610575565b60405190151581526020015b60405180910390f35b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161021f565b6102716208052081565b60405190815260200161021f565b61029261028d366004614085565b6105c7565b005b61029c610731565b60405161021f91906140ee565b6102bc6102b7366004614157565b6107c5565b6040516001600160e01b0319909116815260200161021f565b6102926102e33660046141e2565b610803565b6102716102f6366004614085565b610e91565b6102716276a70081565b6102717f000000000000000000000000000000000000000000000000000000000000000081565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610292610361366004614237565b610ed2565b610379610374366004614085565b610faf565b60405161021f9c9b9a999897969594939291906142b4565b6102717f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa71781565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102136103ed366004614085565b60026020526000908152604090205460ff1681565b610292610410366004614085565b6111c8565b610213610423366004614392565b6113bd565b610271610436366004614237565b6113e9565b610271610449366004614418565b6114b6565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102716201518081565b61048861025881565b60405163ffffffff909116815260200161021f565b6102926104ab3660046144a8565b611939565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610271611b2b565b610271606481565b6102bc6104f5366004614525565b611b47565b61050462f4240081565b60405164ffffffffff909116815260200161021f565b6102716105283660046145e3565b611b62565b6102bc61053b3660046145ff565b611b75565b61027161054e366004614085565b611bb3565b61029c60405180604001604052806003815260200162312e3360e81b81525081565b60006001600160e01b031982166301ffc9a760e01b14806105a657506001600160e01b03198216630a85bd0160e11b145b806105c157506001600160e01b03198216630271189760e51b145b92915050565b6105cf611c48565b6000818152600160205260409081902090516331a9108f60e11b81526004810183905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015610645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106699190614685565b6001600160a01b03161461069057604051632a0a3d8160e11b815260040160405180910390fd5b805460ff166000036106b5576040516335cee39560e01b815260040160405180910390fd5b805460ff166003036106d2576106cd82336000611ca1565b610723565b805460ff1660021480156106f95750600181015442600160c81b90910464ffffffffff1611155b1561070a576106cd82336001611ca1565b6040516311d01f2b60e31b815260040160405180910390fd5b5061072e6001600055565b50565b604051630233557560e41b81523060048201526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632335575090602401600060405180830381865afa158015610798573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107c091908101906146a2565b905090565b60006001600160a01b03861630146107f0576040516382a1dea160e01b815260040160405180910390fd5b50630a85bd0160e11b5b95945050505050565b61080b611c48565b823560009081526001602052604081208054909160ff9091169003610843576040516335cee39560e01b815260040160405180910390fd5b805460ff1660030361086857604051631062e18f60e01b815260040160405180910390fd5b6000610873856113e9565b60008181526002602052604090205490915060ff16610921576108dc61089f60c0870160a08801614743565b8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d8d92505050565b610921576108f060c0860160a08701614743565b6040516301d2d55760e31b81526001600160a01b039091166004820152602481018290526044015b60405180910390fd5b61093160a0860160808701614775565b64ffffffffff164210610978574261094f60a0870160808801614775565b60405163aa2fd92560e01b8152600481019290925264ffffffffff166024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f291a62c6109b760c0880160a08901614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08901356024820152908801356044820152606401602060405180830381865afa158015610a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a33919061479e565b610a8057610a4760c0860160a08701614743565b604051632108c30560e11b81526001600160a01b03909116600482015260c0860135602482015260e08601356044820152606401610918565b6040516331a9108f60e11b8152853560048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0c9190614685565b90506001600160a01b0381163303610b985760028301546001600160a01b0316610b3c60c0880160a08901614743565b6001600160a01b031614610b935760028301546001600160a01b0316610b6860c0880160a08901614743565b604051627c5e8760e31b81526001600160a01b03928316600482015291166024820152604401610918565b610bfe565b60028301546001600160a01b03163303610be5576001600160a01b038116610bc660c0880160a08901614743565b6001600160a01b031614610b935780610b6860c0880160a08901614743565b604051639d29f3a960e01b815260040160405180910390fd5b62015180610c126080880160608901614775565b64ffffffffff161015610c5b57610c2f6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff9091166004820152620151806024820152604401610918565b6276a700610c6f6080880160608901614775565b64ffffffffff161115610cb857610c8c6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff90911660048201526276a7006024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f79924a9610cf760c0890160a08a01614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08a01356024820152908901356044820152606401600060405180830381600087803b158015610d4c57600080fd5b505af1158015610d60573d6000803e3d6000fd5b505050506001830154600160c81b900464ffffffffff16610d876080880160608901614775565b610d9190826147d1565b60018501805464ffffffffff60c81b1916600160c81b64ffffffffff938416810291909117918290556040805185851681529190920490921660208301528835917f16e70f82a9a68fdbf6cc67068dcfadcaf1e0c61409aa3a24122767789ccc20d5910160405180910390a26000610e0f6040890160208a01614743565b6001600160a01b031614158015610e2a575060008760400135115b15610e7e576000610e5760408901803590610e489060208c01614743565b6001600160a01b031690611f33565b9050610e6281611f6b565b6002850154610e7c9082906001600160a01b031685611fd6565b505b50505050610e8c6001600055565b505050565b6000818152600160205260408120805460ff168203610eb35750600092915050565b610ebc8161204e565b8160050154610ecb91906147f6565b9392505050565b610ee260c0820160a08301614743565b6001600160a01b0316336001600160a01b031614610f3457610f0a60c0820160a08301614743565b604051627c5e8760e31b81526001600160a01b039091166004820152336024820152604401610918565b6000610f3f826113e9565b6000818152600260205260409020805460ff191660011790559050610f6a60c0830160a08401614743565b6001600160a01b0316817f3404b1a797c8c84bf93d13290f9f6e7464634602778a1ffa1fc7d8708668022e84604051610fa39190614809565b60405180910390a35050565b600080600080600080600080610fc3614029565b610fcb614029565b60008b81526001602052604081208190610fe48e612101565b9c508060010160149054906101000a900464ffffffffff169b508060010160199054906101000a900464ffffffffff169a508060020160009054906101000a90046001600160a01b031699508060030160009054906101000a90046001600160a01b031698508060000160009054906101000a900460ff1660ff1660000361106d5760006110f6565b6040516331a9108f60e11b8152600481018f90526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f69190614685565b6003820154600483015460058401548454939b50600160a01b90920462ffffff16995097506111339161010090046001600160a01b031690611f33565b60408051608081019091526006830180549297509091829060ff16600381111561115f5761115f614254565b600381111561117057611170614254565b815281546001600160a01b03610100909104811660208301526001808401546040840152600290930154606090920191909152908301549195501692506111b68e610e91565b91505091939597999b5091939597999b565b6111d0611c48565b600081815260016020819052604090912080549181015490916112069160ff90911690600160c81b900464ffffffffff1661214d565b61120f826121c9565b600061121a83610e91565b82549091506112419061123b9061010090046001600160a01b031683611f33565b33612230565b60408051608081019091526006830180546112bb929190829060ff16600381111561126e5761126e614254565b600381111561127f5761127f614254565b815281546001600160a01b036101009091048116602083015260018301546040830152600292830154606090920191909152908501541661229d565b6040516331a9108f60e11b81526004810184905230906394aedc2f90859084907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa15801561132c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113509190614685565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526001600160a01b03166044820152606401600060405180830381600087803b15801561139f57600080fd5b505af19250505080156113b0575060015b50505061072e6001600055565b60006105c1827f00000000000000000000000000000000000000000000000000000000000000006122fd565b60007f00000000000000000000000000000000000000000000000000000000000000007f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa7178360405160200161143e9190614809565b60408051601f198184030181529082905261145c929160200161489f565b6040516020818303038152906040528051906020012060405160200161149992919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b60006114c0611c48565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d019577a6114fc6020890189614743565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401602060405180830381865afa158015611566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158a919061479e565b6115e65761159b6020870187614743565b604051630b92eb2560e11b81526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401610918565b6115f660408501602086016148c5565b1561167f5760408051630a69412f60e21b81523360048201529085013560248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906329a504bc90604401600060405180830381600087803b15801561166657600080fd5b505af115801561167a573d6000803e3d6000fd5b505050505b8335156116ca578335600090815260016020819052604090912080549181015490916116be9160ff90911690600160c81b900464ffffffffff1661214d565b6116c885356121c9565b505b6000806116da6020890189614743565b6001600160a01b03166301e832723388356116f860208d018d6148e2565b61170560408f018f614928565b8f806060019061171591906148e2565b6040518963ffffffff1660e01b815260040161173898979695949392919061499a565b610200604051808303816000875af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190614ab6565b805191935091506001600160a01b031633148015906117a7575061179f87611b62565b8160e0015114155b156117dc578060e001516117ba88611b62565b604051633188f56d60e11b815260048101929092526024820152604401610918565b61025863ffffffff16816040015163ffffffff16101561182557604080820151905163387a058b60e01b815263ffffffff90911660048201526102586024820152604401610918565b62f4240064ffffffffff168160c0015162ffffff16111561186f5760c0810151604051630fb8adc560e41b815262ffffff909116600482015262f424006024820152604401610918565b8535600003611897576118858160800151611f6b565b6118928160600151611f6b565b6118a2565b6118a2863582612319565b6118ac8188612470565b92506118bb6020890189614743565b6001600160a01b031682847f81757c17b6937fd2ab5739a2842fe6165ef6bee2d0b24179f95fbf761634a68a8960000135858c8b8b604051611901959493929190614b96565b60405180910390a485356000036119215761191c81886126a7565b61192d565b61192d86358289612847565b50506107fa6001600055565b3330146119595760405163edd7338f60e01b815260040160405180910390fd5b6000838152600160205260409020805460ff1660031461198b57604051625bdcbf60e11b815260040160405180910390fd5b60038101546001600160a01b038381169116146119bb5760405163499174ef60e01b815260040160405180910390fd5b600181015481546001600160a01b03918216916000916119e2916101009091041686611f33565b90506119ed86612c3f565b60405160009087907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b73908390a384600003611a2a57505050505050565b836001600160a01b0316826001600160a01b031603611a5257611a4d818561229d565b611b23565b60405163b209123160e01b81526001600160a01b0383811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063b209123190602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190614685565b90506001600160a01b038116611b1557604051632f9526c360e11b81526001600160a01b0384166004820152602401610918565b611b2182828588612d35565b505b505050505050565b611b39620805206064614c5a565b611b44906064614c5a565b81565b60006040516382a1dea160e01b815260040160405180910390fd5b6000816040516020016114999190614c79565b60006001600160a01b0387163014611ba0576040516382a1dea160e01b815260040160405180910390fd5b5063f23a6e6160e01b9695505050505050565b6000818152600160205260408120805460ff168203611bd55750600092915050565b611bde83612101565b6001820154600483015460038401546040805160ff9095166020860152600160c81b90930464ffffffffff16928401929092526060830152600160a01b900462ffffff16608082015260a00160405160208183030381529060405280519060200120915050919050565b600260005403611c9a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610918565b6002600055565b60008381526001602052604081209082611cdc57611cd7611cc186610e91565b835461010090046001600160a01b031690611f33565b611d42565b6040805160808101909152600683018054829060ff166003811115611d0357611d03614254565b6003811115611d1457611d14614254565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546060909101525b9050611d4d85612c3f565b6040518315159086907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b7390600090a3611d86818561229d565b5050505050565b60006001600160a01b0384163b15611e8857600080856001600160a01b0316631626ba7e60e01b8686604051602401611dc7929190614c99565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611e059190614cb2565b600060405180830381855afa9150503d8060008114611e40576040519150601f19603f3d011682016040523d82523d6000602084013e611e45565b606091505b5091509150818015611e58575080516020145b8015611e7f57508051630b135d3f60e11b90611e7d9083016020908101908401614cce565b145b92505050610ecb565b60008060008451604103611eb05750505060208201516040830151606084015160001a611f07565b8451604003611ee957602085015160408601519093506001600160ff1b0381169250611ee160ff82901c601b6147f6565b915050611f07565b845160405163058676ad60e31b815260040161091891815260200190565b611f1386828585612e36565b6001600160a01b0316876001600160a01b03161493505050509392505050565b611f3b614029565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b611f74816113bd565b61072e5780516003811115611f8b57611f8b614254565b60208201516040808401516060850151915163032163e160e11b815260ff90941660048501526001600160a01b03909216602484015260448301919091526064820152608401610918565b6000611fe28483612e5e565b9050611fef8484846130a8565b611ffd8482848660016130b5565b816001600160a01b0316836001600160a01b03167f0272ef83f5953daad3d7708e6b4442e126f1e049e62a01c1fc53683f3277199c866040516120409190614ce7565b60405180910390a350505050565b6003810154600090600160a01b900462ffffff16810361207057506004015490565b6001820154600090603c9061209390600160a01b900464ffffffffff1642614cf5565b61209d9190614d1e565b600584015460038501549192506000916120e791906120c9908590600160a01b900462ffffff16614c5a565b6120d7620805206064614c5a565b6120e2906064614c5a565b61314f565b90508084600401546120f991906147f6565b949350505050565b6000818152600160205260408120805460ff1660021480156121365750600181015442600160c81b90910464ffffffffff1611155b61214457805460ff16610ecb565b60049392505050565b8160ff16600003612171576040516335cee39560e01b815260040160405180910390fd5b8160ff16600214612195576040516331fe4d5d60e01b815260040160405180910390fd5b428164ffffffffff16116121c557604051631e3cd61560e01b815264ffffffffff82166004820152602401610918565b5050565b6000818152600160205260409020805460ff191660031781556121eb8161204e565b600482015560038101805462ffffff60a01b1916905560405182907ff1e5b832ef53e7d611651983b38ff941f4d2049e9c8962c623c2664bca312bc090600090a25050565b600061223c8330612e5e565b9050612249838330613239565b6122578382308560016130b5565b816001600160a01b03167f019fcaae912e42069954835069f1c8184411022f86cf749694625f2a2313b6ab846040516122909190614ce7565b60405180910390a2505050565b60006122a98383612e5e565b90506122b68330846130a8565b6122c48382843060016130b5565b816001600160a01b03167fc2b8da69776ffa72ca2d7c4a31390d57bd4871cef8066bbe7f1e5bf220a310f1846040516122909190614ce7565b60006123098383613246565b8015610ecb5750610ecb836132f4565b6000828152600160209081526040909120608083015190910151815461010090046001600160a01b03908116911614158061235a5750608082015160600151155b1561237857604051635f860c6160e11b815260040160405180910390fd5b606082015151600381111561238f5761238f614254565b600682015460ff1660038111156123a8576123a8614254565b1415806123d35750606082015160200151600682015461010090046001600160a01b03908116911614155b806123ea5750606082015160400151600782015414155b8061240057506060808301510151600882015414155b1561241e5760405163175bb1b760e21b815260040160405180910390fd5b602082015160028201546001600160a01b03908116911614610e8c576002810154602083015160405163d4b919f760e01b81526001600160a01b03928316600482015291166024820152604401610918565b81516040516335313c2160e11b81526001600160a01b0391821660048201526000917f00000000000000000000000000000000000000000000000000000000000000001690636a627842906024016020604051808303816000875af11580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190614cce565b6000818152600160209081526040909120805460808701518301516001600160a01b0316610100026001600160a81b031990911617600217815591925061254a90840184614743565b60018201805464ffffffffff42908116600160a01b026001600160c81b03199092166001600160a01b03949094169390931717905560408501516125969163ffffffff909116906147d1565b6001808301805464ffffffffff93909316600160c81b0264ffffffffff60c81b199093169290921790915560208501516002830180546001600160a01b039283166001600160a01b031990911617905585516003808501805460c08a015162ffffff16600160a01b026001600160b81b0319909116939094169290921792909217905560a08601516004840155608086015160609081015160058501558601518051600685018054929490939192849260ff199091169190849081111561265f5761265f614254565b0217905550602082015181546001600160a01b0390911661010002610100600160a81b0319909116178155604082015160018201556060909101516002909101555092915050565b6126b982606001518360200151612230565b81516001600160a01b03166126d16020830183614743565b6001600160a01b0316146126ee576126ee826080015183836133d2565b6000806127847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127769190614d40565b8560800151606001516134e3565b60808601519193509150821561282e578281606001818152505061282e8186600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128299190614685565b611fd6565b6060810182905284516020860151611d86918391611fd6565b60008381526001602052604080822090516331a9108f60e11b8152600481018690529091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156128bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e19190614685565b905060006128ee86610e91565b90506000806129867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612954573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129789190614d40565b8860800151606001516134e3565b9150915060006129968483613524565b905060008483116129a85760006129b2565b6129b28584614cf5565b905060008082116129cc576129c78487614cf5565b6129cf565b60005b90506000876001600160a01b03168b600001516001600160a01b0316141580612a2f575060038901546001600160a01b038981169116148015612a2f5750612a1a60208b018b614743565b60018a01546001600160a01b03908116911614155b60808c01518c51919250906001600160a01b0316612a5060208d018d614743565b6001600160a01b031614612a91578382612a6b576000612a6d565b855b612a7790896147f6565b612a8191906147f6565b6060820152612a91818d8d6133d2565b8615612b085786816060018181525050612b08818d600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b8115612b2257606081018590528b51612b22908290612230565b8315612b4657606081018490528b5160208d0151612b41918391611fd6565b612b63565b8215612b63576060810183905260208c0151612b63908290612230565b306394aedc2f8e8585612b77576000612b79565b885b612b8391906147f6565b6040516001600160e01b031960e085901b168152600481019290925260248201526001600160a01b038c166044820152606401600060405180830381600087803b158015612bd057600080fd5b505af1925050508015612be1575060015b612c305781612c3057606081018590528b516001600160a01b0316612c0960208d018d614743565b6001600160a01b031614612c2257612c22818d8d6133d2565b612c30818d60000151612230565b50505050505050505050505050565b604051630852cd8d60e31b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b158015612ca157600080fd5b505af1158015612cb5573d6000803e3d6000fd5b505050600091825250600160208190526040822080546001600160a81b0319908116825591810180546001600160f01b03191690556002810180546001600160a01b03191690556003810180546001600160b81b031916905560048101839055600581018390556006810180549092169091556007810182905560080155565b6000612d418530612e5e565b9050612d4e853086613239565b6020850151606086015160405163107c8ed760e01b81526001600160a01b0386811660048301528581166024830152928316604482015260648101919091529085169063107c8ed790608401600060405180830381600087803b158015612db457600080fd5b505af1158015612dc8573d6000803e3d6000fd5b50505050612dda8582308660006130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167fb58f4e60b4600784c073e07e7bb67825fe64b4592b5c7ce254599a9b8dcc4d8288604051612e279190614ce7565b60405180910390a45050505050565b6000806000612e478787878761353a565b91509150612e54816135fe565b5095945050505050565b60008083516003811115612e7457612e74614254565b03612ef15760208301516040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024015b602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190614cce565b90506105c1565b600183516003811115612f0657612f06614254565b03612fae57816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b602060405180830381865afa158015612f68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8c9190614685565b6001600160a01b031614612fa1576000612fa4565b60015b60ff1690506105c1565b600283516003811115612fc357612fc3614254565b036130065760208301516040808501519051627eeac760e11b81526001600160a01b038581166004830152602482019290925291169062fdd58e90604401612ea9565b60038351600381111561301b5761301b614254565b0361306057816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b60405162461bcd60e51b815260206004820181905260248201527f4d756c7469546f6b656e3a20556e737570706f727465642063617465676f72796044820152606401610918565b610e8c8383836001613748565b816001600160a01b0316836001600160a01b0316036130f25760405163bb77337360e01b81526001600160a01b0384166004820152602401610918565b6000816131115761310286613a01565b61310c9086614cf5565b613124565b61311a86613a01565b61312490866147f6565b90506131308685612e5e565b8114611b23576040516345ffc53d60e11b815260040160405180910390fd5b60008080600019858709858702925082811083820303915050806000036131895783828161317f5761317f614d08565b0492505050610ecb565b8084116131d05760405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606401610918565b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b610e8c8383836000613748565b6020820151604051638481ab0760e01b81526001600160a01b039182166004820152600091829190841690638481ab0790602401602060405180830381865afa158015613297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bb9190614d64565b905060ff808216146132eb57835160ff82169060038111156132df576132df614254565b60ff16149150506105c1565b6120f984613a5c565b6000808251600381111561330a5761330a614254565b036133265760408201511561332157506000919050565b6133ca565b60018251600381111561333b5761333b614254565b036133525760608201511561332157506000919050565b60028251600381111561336757613367614254565b146133ca5760038251600381111561338157613381614254565b036133985760608201511561332157506000919050565b815160038111156133ab576133ab614254565b604051635928f9a360e11b815260ff9091166004820152602401610918565b506001919050565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b20912316134106020850185614743565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015613454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134789190614685565b90506001600160a01b0381166134ba576134956020830183614743565b604051632f9526c360e11b81526001600160a01b039091166004820152602401610918565b6060840151156134dd576134dd84826134d66020860186614743565b8651613bf2565b50505050565b6000808361ffff166000036134fd5750600090508161351d565b61350e838561ffff1661271061314f565b915061351a8284614cf5565b90505b9250929050565b60008183106135335781610ecb565b5090919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561357157506000905060036135f5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135c5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ee576000600192509250506135f5565b9150600090505b94509492505050565b600081600481111561361257613612614254565b0361361a5750565b600181600481111561362e5761362e614254565b0361367b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610918565b600281600481111561368f5761368f614254565b036136dc5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610918565b60038160048111156136f0576136f0614254565b0361072e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610918565b60008451600381111561375d5761375d614254565b036137c557306001600160a01b0384160361379d5761379882856060015186602001516001600160a01b0316613cd99092919063ffffffff16565b6134dd565b6137988383866060015187602001516001600160a01b0316613d3c909392919063ffffffff16565b6001845160038111156137da576137da614254565b036138b5578061385f57602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd906064015b600060405180830381600087803b15801561384257600080fd5b505af1158015613856573d6000803e3d6000fd5b505050506134dd565b60208401516040808601519051635c46a7ef60e11b81526001600160a01b03868116600483015285811660248301526044820192909252608060648201526000608482015291169063b88d4fde9060a401613828565b6002845160038111156138ca576138ca614254565b0361394f5783602001516001600160a01b031663f242432a8484876040015188606001516000146138ff578860600151613902565b60015b6040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260a06084820152600060a482015260c401613828565b60038451600381111561396457613964614254565b0361306057306001600160a01b038416036139b9576020840151604080860151905163a9059cbb60e01b81526001600160a01b038581166004830152602482019290925291169063a9059cbb90604401613828565b602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd90606401613828565b60008082516003811115613a1757613a17614254565b03613a2457506060015190565b600282516003811115613a3957613a39614254565b148015613a4a575060008260600151115b156133ca57506060015190565b919050565b60008082516003811115613a7257613a72614254565b03613b4757613a8d82602001516001600160a01b0316613d74565b15613b33576020820151613ab1906001600160a01b03166336372b0760e01b613d9c565b15613abe57506001919050565b6020820151613add906001600160a01b03166380ac58cd60e01b613d9c565b158015613b0657506020820151613b04906001600160a01b0316636cdb3d1360e11b613d9c565b155b80156105c157506020820151613b2c906001600160a01b0316639a20483d60e01b613d9c565b1592915050565b50602001516001600160a01b03163b151590565b600182516003811115613b5c57613b5c614254565b03613b805760208201516105c1906001600160a01b03166380ac58cd60e01b613e25565b600282516003811115613b9557613b95614254565b03613bb95760208201516105c1906001600160a01b0316636cdb3d1360e11b613e25565b600382516003811115613bce57613bce614254565b036133985760208201516105c1906001600160a01b0316639a20483d60e01b613e25565b6000613bfe8583612e5e565b60208601516060870151604051630b620b8160e01b81526001600160a01b038781166004830152868116602483015292831660448201526064810191909152919250851690630b620b8190608401600060405180830381600087803b158015613c6657600080fd5b505af1158015613c7a573d6000803e3d6000fd5b50505050613c8c8582848660016130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167f4c6641e50ab591b51c5b75ab0d3721eb0357eac106223e5d21b1ceb5c2abd30388604051612e279190614ce7565b6040516001600160a01b038316602482015260448101829052610e8c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613e41565b6040516001600160a01b03808516602483015283166044820152606481018290526134dd9085906323b872dd60e01b90608401613d05565b6000613d87826301ffc9a760e01b613d9c565b80156105c15750613b2c826001600160e01b03195b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015613e0e575060208210155b8015613e1a5750600081115b979650505050505050565b6000613e3083613d74565b8015610ecb5750610ecb8383613d9c565b6000613e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f169092919063ffffffff16565b9050805160001480613eb7575080806020019051810190613eb7919061479e565b610e8c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610918565b60606120f9848460008585600080866001600160a01b03168587604051613f3d9190614cb2565b60006040518083038185875af1925050503d8060008114613f7a576040519150601f19603f3d011682016040523d82523d6000602084013e613f7f565b606091505b5091509150613e1a8783838760608315613ffa578251600003613ff3576001600160a01b0385163b613ff35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610918565b50816120f9565b6120f9838381511561400f5781518083602001fd5b8060405162461bcd60e51b815260040161091891906140ee565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b60006020828403121561406d57600080fd5b81356001600160e01b031981168114610ecb57600080fd5b60006020828403121561409757600080fd5b5035919050565b60005b838110156140b95781810151838201526020016140a1565b50506000910152565b600081518084526140da81602086016020860161409e565b601f01601f19169290920160200192915050565b602081526000610ecb60208301846140c2565b6001600160a01b038116811461072e57600080fd5b60008083601f84011261412857600080fd5b5081356001600160401b0381111561413f57600080fd5b60208301915083602082850101111561351d57600080fd5b60008060008060006080868803121561416f57600080fd5b853561417a81614101565b9450602086013561418a81614101565b93506040860135925060608601356001600160401b038111156141ac57600080fd5b6141b888828901614116565b969995985093965092949392505050565b600061010082840312156141dc57600080fd5b50919050565b600080600061012084860312156141f857600080fd5b61420285856141c9565b92506101008401356001600160401b0381111561421e57600080fd5b61422a86828701614116565b9497909650939450505050565b6000610100828403121561424a57600080fd5b610ecb83836141c9565b634e487b7160e01b600052602160045260246000fd5b80516004811061428a57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b03169083015260408082015190830152606090810151910152565b60ff8d16815264ffffffffff8c811660208301528b1660408201526001600160a01b038a811660608301528981166080830152881660a082015262ffffff871660c082015260e08101869052610240810161431361010083018761426a565b61432161018083018661426a565b6001600160a01b039390931661020082015261022001529a9950505050505050505050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561437f5761437f614346565b60405290565b6004811061072e57600080fd5b6000608082840312156143a457600080fd5b604051608081018181106001600160401b03821117156143c6576143c6614346565b60405282356143d481614385565b815260208301356143e481614101565b6020820152604083810135908201526060928301359281019290925250919050565b6000602082840312156141dc57600080fd5b600080600080600085870360c081121561443157600080fd5b86356001600160401b038082111561444857600080fd5b908801906080828b03121561445c57600080fd5b81975061446c8a60208b01614406565b96506060603f198401121561448057600080fd5b60408901955060a089013592508083111561449a57600080fd5b50506141b888828901614116565b6000806000606084860312156144bd57600080fd5b833592506020840135915060408401356144d681614101565b809150509250925092565b60008083601f8401126144f357600080fd5b5081356001600160401b0381111561450a57600080fd5b6020830191508360208260051b850101111561351d57600080fd5b60008060008060008060008060a0898b03121561454157600080fd5b883561454c81614101565b9750602089013561455c81614101565b965060408901356001600160401b038082111561457857600080fd5b6145848c838d016144e1565b909850965060608b013591508082111561459d57600080fd5b6145a98c838d016144e1565b909650945060808b01359150808211156145c257600080fd5b506145cf8b828c01614116565b999c989b5096995094979396929594505050565b6000602082840312156145f557600080fd5b610ecb8383614406565b60008060008060008060a0878903121561461857600080fd5b863561462381614101565b9550602087013561463381614101565b9450604087013593506060870135925060808701356001600160401b0381111561465c57600080fd5b61466889828a01614116565b979a9699509497509295939492505050565b8051613a5781614101565b60006020828403121561469757600080fd5b8151610ecb81614101565b6000602082840312156146b457600080fd5b81516001600160401b03808211156146cb57600080fd5b818401915084601f8301126146df57600080fd5b8151818111156146f1576146f1614346565b604051601f8201601f19908116603f0116810190838211818310171561471957614719614346565b8160405282815287602084870101111561473257600080fd5b613e1a83602083016020880161409e565b60006020828403121561475557600080fd5b8135610ecb81614101565b803564ffffffffff81168114613a5757600080fd5b60006020828403121561478757600080fd5b610ecb82614760565b801515811461072e57600080fd5b6000602082840312156147b057600080fd5b8151610ecb81614790565b634e487b7160e01b600052601160045260246000fd5b64ffffffffff8181168382160190808211156147ef576147ef6147bb565b5092915050565b808201808211156105c1576105c16147bb565b813581526101008101602083013561482081614101565b6001600160a01b031660208301526040838101359083015261484460608401614760565b64ffffffffff80821660608501528061485f60808701614760565b166080850152505060a083013561487581614101565b6001600160a01b03811660a08401525060c083013560c083015260e083013560e083015292915050565b828152600082516148b781602085016020870161409e565b919091016020019392505050565b6000602082840312156148d757600080fd5b8135610ecb81614790565b6000808335601e198436030181126148f957600080fd5b8301803591506001600160401b0382111561491357600080fd5b60200191503681900382131561351d57600080fd5b6000808335601e1984360301811261493f57600080fd5b8301803591506001600160401b0382111561495957600080fd5b6020019150600581901b360382131561351d57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038916815287602082015260a0604082015260006149c260a08301888a614971565b82810360608401528581526001600160fb1b038611156149e157600080fd5b8560051b808860208401370182810360209081016080850152614a079082018587614971565b9b9a5050505050505050505050565b805163ffffffff81168114613a5757600080fd5b600060808284031215614a3c57600080fd5b604051608081018181106001600160401b0382111715614a5e57614a5e614346565b80604052508091508251614a7181614385565b81526020830151614a8181614101565b8060208301525060408301516040820152606083015160608201525092915050565b805162ffffff81168114613a5757600080fd5b600080828403610200811215614acb57600080fd5b835192506101e080601f1983011215614ae357600080fd5b614aeb61435c565b9150614af96020860161467a565b8252614b076040860161467a565b6020830152614b1860608601614a16565b6040830152614b2a8660808701614a2a565b6060830152610100614b3e87828801614a2a565b608084015261018086015160a0840152614b5b6101a08701614aa3565b60c08401526101c086015160e0840152940151938101939093525092909150565b8035614b8781614101565b6001600160a01b031690915250565b85815284516001600160a01b03166020820152600061024060208701516001600160a01b038116604085015250604087015163ffffffff81166060850152506060870151614be7608085018261426a565b506080870151610100614bfc8186018361426a565b60a089015161018086015260c089015162ffffff166101a086015260e08901516101c08601528801516101e085015250614c3a610200840187614b7c565b80610220840152614c4e8184018587614971565b98975050505050505050565b6000816000190483118215151615614c7457614c746147bb565b500290565b602081018235614c8881614101565b6001600160a01b0316909152919050565b8281526040602082015260006120f960408301846140c2565b60008251614cc481846020870161409e565b9190910192915050565b600060208284031215614ce057600080fd5b5051919050565b608081016105c1828461426a565b818103818111156105c1576105c16147bb565b634e487b7160e01b600052601260045260246000fd5b600082614d3b57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215614d5257600080fd5b815161ffff81168114610ecb57600080fd5b600060208284031215614d7657600080fd5b815160ff81168114610ecb57600080fdfea2646970667358221220825b2223fc99b9fa96f255726855d28b700266f4ef852c01cd8fe06f1662a89d64736f6c63430008100033","sourceMap":"1359:46454:93:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11525:298:102;;;;;;:::i;:::-;;:::i;:::-;;;470:14:137;;463:22;445:41;;433:2;418:18;11525:298:102;;;;;;;;2896:34:93;;;;;;;;-1:-1:-1;;;;;678:32:137;;;660:51;;648:2;633:18;2896:34:93;497:220:137;1955:49:93;;1997:7;1955:49;;;;;868:25:137;;;856:2;841:18;1955:49:93;722:177:137;32058:859:93;;;;;;:::i;:::-;;:::i;:::-;;46535:135;;;:::i;:::-;;;;;;;:::i;8944:341:102:-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3254:33:137;;;3236:52;;3224:2;3209:18;8944:341:102;3092:202:137;38008:3666:93;;;;;;:::i;:::-;;:::i;30557:323::-;;;;;;:::i;:::-;;:::i;2168:56::-;;2217:7;2168:56;;2552:304;;;;;2863:27;;;;;37170:513;;;;;;:::i;:::-;;:::i;43568:1139::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;2292:253::-;;2346:199;2292:253;;3026:61;;;;;8344:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;27796:956;;;;;;:::i;:::-;;:::i;45557:147::-;;;;;;:::i;:::-;;:::i;41845:347::-;;;;;;:::i;:::-;;:::i;14272:3571::-;;;;;;:::i;:::-;;:::i;2936:33::-;;;;;2230:55;;2279:6;2230:55;;1735:53;;1778:10;1735:53;;;;;10114:10:137;10102:23;;;10084:42;;10072:2;10057:18;1735:53:93;9940:192:137;33581:2191:93;;;;;;:::i;:::-;;:::i;2975:45::-;;;;;2047:114;;;:::i;1889:60::-;;1946:3;1889:60;;10676:295:102;;;;;;:::i;:::-;;:::i;1794:55:93:-;;1845:4;1794:55;;;;;12647:12:137;12635:25;;;12617:44;;12605:2;12590:18;1794:55:93;12473:194:137;13449:146:93;;;;;;:::i;:::-;;:::i;9782:366:102:-;;;;;;:::i;:::-;;:::i;46923:887:93:-;;;;;;:::i;:::-;;:::i;1488:38::-;;;;;;;;;;;;;;;-1:-1:-1;;;1488:38:93;;;;;11525:298:102;11612:4;-1:-1:-1;;;;;;11647:40:102;;-1:-1:-1;;;11647:40:102;;:104;;-1:-1:-1;;;;;;;11703:48:102;;-1:-1:-1;;;11703:48:102;11647:104;:169;;;-1:-1:-1;;;;;;;11767:49:102;;-1:-1:-1;;;11767:49:102;11647:169;11628:188;11525:298;-1:-1:-1;;11525:298:102:o;32058:859:93:-;2261:21:46;:19;:21::i;:::-;32125:17:93::1;32145:13:::0;;;:5:::1;:13;::::0;;;;;;32223:25;;-1:-1:-1;;;32223:25:93;;::::1;::::0;::::1;868::137::0;;;32252:10:93::1;::::0;-1:-1:-1;;;;;32223:9:93::1;:17;::::0;::::1;::::0;841:18:137;;32223:25:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;32223:39:93::1;;32219:90;;32283:26;;-1:-1:-1::0;;;32283:26:93::1;;;;;;;;;;;32219:90;32324:11:::0;;::::1;;;:16:::0;32320:590:::1;;32431:17;;-1:-1:-1::0;;;32431:17:93::1;;;;;;;;;;;32320:590;32467:11:::0;;::::1;;32482:1;32467:16:::0;32463:447:::1;;32536:77;32563:6;32582:10;32605:5;32536:16;:77::i;:::-;32463:447;;;32632:11:::0;;::::1;;32647:1;32632:16;:60:::0;::::1;;;-1:-1:-1::0;32652:21:93::1;::::0;::::1;::::0;32677:15:::1;-1:-1:-1::0;;;32652:21:93;;::::1;;;:40;;32632:60;32628:282;;;32749:76;32776:6;32795:10;32818:4;32749:16;:76::i;32628:282::-;32897:13;;-1:-1:-1::0;;;32897:13:93::1;;;;;;;;;;;32628:282;32115:802;2303:20:46::0;1716:1;2809:7;:22;2629:209;2303:20;32058:859:93;:::o;46535:135::-;46626:37;;-1:-1:-1;;;46626:37:93;;46657:4;46626:37;;;660:51:137;46594:13:93;;46626:6;-1:-1:-1;;;;;46626:22:93;;;;633:18:137;;46626:37:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46626:37:93;;;;;;;;;;;;:::i;:::-;46619:44;;46535:135;:::o;8944:341:102:-;9122:6;-1:-1:-1;;;;;9144:25:102;;9164:4;9144:25;9140:79;;9190:29;;-1:-1:-1;;;9190:29:102;;;;;;;;;;;9140:79;-1:-1:-1;;;;8944:341:102;;;;;;;;:::o;38008:3666:93:-;2261:21:46;:19;:21::i;:::-;38172:16:93;::::1;38146:17;38166:23:::0;;;:5:::1;:23;::::0;;;;38253:11;;38166:23;;38253:11:::1;::::0;;::::1;:16:::0;;38249:58:::1;;38290:17;;-1:-1:-1::0;;;38290:17:93::1;;;;;;;;;;;38249:58;38321:11:::0;;::::1;;38336:1;38321:16:::0;38317:82:::1;;38387:12;;-1:-1:-1::0;;;38387:12:93::1;;;;;;;;;;;38317:82;38446:21;38470:27;38487:9;38470:16;:27::i;:::-;38512:37;::::0;;;:22:::1;:37;::::0;;;;;38446:51;;-1:-1:-1;38512:37:93::1;;38507:262;;38568:85;38608:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;38628:13;38643:9;;38568:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;38568:39:93::1;::::0;-1:-1:-1;;;38568:85:93:i:1;:::-;38563:206;;38725:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;38678:91;::::0;-1:-1:-1;;;38678:91:93;;-1:-1:-1;;;;;15703:32:137;;;38678:91:93::1;::::0;::::1;15685:51:137::0;15752:18;;;15745:34;;;15658:18;;38678:91:93::1;;;;;;;;38563:206;38841:20;::::0;;;::::1;::::0;::::1;;:::i;:::-;38822:39;;:15;:39;38818:135;;38901:15;38930:20;::::0;;;::::1;::::0;::::1;;:::i;:::-;38882:71;::::0;-1:-1:-1;;;38882:71:93;;::::1;::::0;::::1;16322:25:137::0;;;;16395:12;16383:25;16363:18;;;16356:53;16295:18;;38882:71:93::1;16149:266:137::0;38818:135:93::1;-1:-1:-1::0;;;;;39002:12:93::1;:26;;39029:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;39002:85;::::0;39071:15:::1;39002:85:::0;;;-1:-1:-1;;;;;;39002:85:93;;;-1:-1:-1;;;;;16640:32:137;;;;39002:85:93::1;::::0;::::1;16622:51:137::0;39049:20:93::1;::::0;::::1;;16689:18:137::0;;;16682:34;39071:15:93;;::::1;;16732:18:137::0;;;16725:34;16595:18;;39002:85:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38997:289;;39163:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;39108:178;::::0;-1:-1:-1;;;39108:178:93;;-1:-1:-1;;;;;16640:32:137;;;39108:178:93::1;::::0;::::1;16622:51:137::0;39211:20:93::1;::::0;::::1;;16689:18:137::0;;;16682:34;39256:15:93::1;::::0;::::1;;16732:18:137::0;;;16725:34;16595:18;;39108:178:93::1;16420:345:137::0;38997:289:93::1;39352:35;::::0;-1:-1:-1;;;39352:35:93;;39370:16;::::1;39352:35;::::0;::::1;868:25:137::0;39332:17:93::1;::::0;39352:9:::1;-1:-1:-1::0;;;;;39352:17:93::1;::::0;::::1;::::0;841:18:137;;39352:35:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39332:55:::0;-1:-1:-1;;;;;;39401:23:93;::::1;:10;:23:::0;39397:795:::1;;39466:13;::::0;::::1;::::0;-1:-1:-1;;;;;39466:13:93::1;39444:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;39444:35:93::1;;39440:286;;39630:13;::::0;::::1;::::0;-1:-1:-1;;;;;39630:13:93::1;39674:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;39576:135;::::0;-1:-1:-1;;;39576:135:93;;-1:-1:-1;;;;;17373:15:137;;;39576:135:93::1;::::0;::::1;17355:34:137::0;17425:15;;17405:18;;;17398:43;17290:18;;39576:135:93::1;17143:304:137::0;39440:286:93::1;39397:795;;;39760:13;::::0;::::1;::::0;-1:-1:-1;;;;;39760:13:93::1;39746:10;:27:::0;39742:450:::1;;-1:-1:-1::0;;;;;39793:31:93;::::1;:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;39793:31:93::1;;39789:278;;39975:9:::0;40015:18:::1;::::0;;;::::1;::::0;::::1;;:::i;39742:450::-;40157:24;;-1:-1:-1::0;;;40157:24:93::1;;;;;;;;;;;39742:450;2279:6;40238:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;:43;;;40234:201;;;40355:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40302:133;::::0;-1:-1:-1;;;40302:133:93;;17655:12:137;17643:25;;;40302:133:93::1;::::0;::::1;17625:44:137::0;2279:6:93::1;17685:18:137::0;;;17678:34;17598:18;;40302:133:93::1;17452:266:137::0;40234:201:93::1;2217:7;40449:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;:43;;;40445:201;;;40566:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40513:133;::::0;-1:-1:-1;;;40513:133:93;;17655:12:137;17643:25;;;40513:133:93::1;::::0;::::1;17625:44:137::0;2217:7:93::1;17685:18:137::0;;;17678:34;17598:18;;40513:133:93::1;17452:266:137::0;40445:201:93::1;-1:-1:-1::0;;;;;40700:12:93::1;:24;;40725:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40700:83;::::0;40767:15:::1;40700:83:::0;;;-1:-1:-1;;;;;;40700:83:93;;;-1:-1:-1;;;;;16640:32:137;;;;40700:83:93::1;::::0;::::1;16622:51:137::0;40745:20:93::1;::::0;::::1;;16689:18:137::0;;;16682:34;40767:15:93;;::::1;;16732:18:137::0;;;16725:34;16595:18;;40700:83:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;40851:21:93::1;::::0;::::1;::::0;-1:-1:-1;;;40851:21:93;::::1;;;40933:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40906:45;::::0;:24;:45:::1;:::i;:::-;40882:21;::::0;::::1;:69:::0;;-1:-1:-1;;;;40882:69:93::1;-1:-1:-1::0;;;40882:69:93::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;40989:187:::1;::::0;;18253:15:137;;;18235:34;;41144:21:93;;;::::1;::::0;;::::1;18300:2:137::0;18285:18;;18278:43;41024:16:93;::::1;::::0;40989:187:::1;::::0;18177:18:137;40989:187:93::1;;;;;;;41286:1;41245:29;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;41245:43:93::1;;;:79;;;;;41323:1;41292:9;:28;;;:32;41245:79;41241:427;;;41340:36;41379:65;41415:28;::::0;::::1;::::0;::::1;::::0;41379:29:::1;::::0;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;41379:35:93::1;::::0;::::1;:65::i;:::-;41340:104;;41508:30;41525:12;41508:16;:30::i;:::-;41632:13;::::0;::::1;::::0;41608:49:::1;::::0;41618:12;;-1:-1:-1;;;;;41632:13:93::1;41647:9:::0;41608::::1;:49::i;:::-;41326:342;41241:427;38136:3538;;;;2303:20:46::0;1716:1;2809:7;:22;2629:209;2303:20;38008:3666:93;;;:::o;30557:323::-;30623:7;30662:13;;;:5;:13;;;;;30725:11;;;;:16;;30721:30;;-1:-1:-1;30750:1:93;;30557:323;-1:-1:-1;;30557:323:93:o;30721:30::-;30847:26;30868:4;30847:20;:26::i;:::-;30824:4;:20;;;:49;;;;:::i;:::-;30817:56;30557:323;-1:-1:-1;;;30557:323:93:o;37170:513::-;37319:18;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37305:32:93;:10;-1:-1:-1;;;;;37305:32:93;;37301:133;;37392:18;;;;;;;;:::i;:::-;37358:76;;-1:-1:-1;;;37358:76:93;;-1:-1:-1;;;;;17373:15:137;;;37358:76:93;;;17355:34:137;37421:10:93;17405:18:137;;;17398:43;17290:18;;37358:76:93;17143:304:137;37301:133:93;37488:21;37512:27;37529:9;37512:16;:27::i;:::-;37549:37;;;;:22;:37;;;;;:44;;-1:-1:-1;;37549:44:93;37589:4;37549:44;;;37488:51;-1:-1:-1;37646:18:93;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37609:67:93;37631:13;37609:67;37666:9;37609:67;;;;;;:::i;:::-;;;;;;;;37248:435;37170:513;:::o;43568:1139::-;43633:12;43655:21;43686:23;43719:16;43745:22;43777:17;43804:26;43840:27;43877:30;;:::i;:::-;43917:34;;:::i;:::-;43961:29;44060:13;;;:5;:13;;;;;43961:29;;44093:22;44066:6;44093:14;:22::i;:::-;44084:31;;44142:4;:19;;;;;;;;;;;;44125:36;;44190:4;:21;;;;;;;;;;;;44171:40;;44232:4;:13;;;;;;;;;;-1:-1:-1;;;;;44232:13:93;44221:24;;44272:4;:19;;;;;;;;;;-1:-1:-1;;;;;44272:19:93;44255:36;;44313:4;:11;;;;;;;;;;;;:16;;44328:1;44313:16;:57;;44368:1;44313:57;;;44332:25;;-1:-1:-1;;;44332:25:93;;;;;868::137;;;-1:-1:-1;;;;;44332:9:93;:17;;;;841:18:137;;44332:25:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44402:24;;;;44458;;;;44526:20;;;;44501:18;;44301:69;;-1:-1:-1;;;;44402:24:93;;;;;;-1:-1:-1;44458:24:93;-1:-1:-1;44501:46:93;;44402:24;44501:18;;-1:-1:-1;;;;;44501:18:93;;:24;:46::i;:::-;44557:28;;;;;;;;;44570:15;;;44557:28;;44492:55;;-1:-1:-1;44557:28:93;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;44557:28:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44619:26;;;;44557:28;;-1:-1:-1;44619:26:93;;-1:-1:-1;44673:27:93;44693:6;44673:19;:27::i;:::-;44655:45;;44030:677;43568:1139;;;;;;;;;;;;;:::o;27796:956::-;2261:21:46;:19;:21::i;:::-;27863:17:93::1;27883:13:::0;;;:5:::1;:13;::::0;;;;;;;27929:11;;27942:21;;::::1;::::0;27883:13;;27907:57:::1;::::0;27929:11:::1;::::0;;::::1;::::0;-1:-1:-1;;;27942:21:93;::::1;;;27907;:57::i;:::-;28014:25;28032:6;28014:17;:25::i;:::-;28101:23;28127:27;28147:6;28127:19;:27::i;:::-;28170:18:::0;;28101:53;;-1:-1:-1;28164:60:93::1;::::0;28170:41:::1;::::0;:18:::1;::::0;::::1;-1:-1:-1::0;;;;;28170:18:93::1;28101:53:::0;28170:24:::1;:41::i;:::-;28213:10;28164:5;:60::i;:::-;28283:37;::::0;;::::1;::::0;::::1;::::0;;;28289:15:::1;::::0;::::1;28283:37:::0;;::::1;::::0;;28289:15;28283:37;;::::1;;;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;;;-1:-1:-1;;;;;28283:37:93::1;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;28306:13;;::::1;::::0;::::1;28283:5;:37::i;:::-;28417:25;::::0;-1:-1:-1;;;28417:25:93;;::::1;::::0;::::1;868::137::0;;;28368:4:93::1;::::0;:23:::1;::::0;28392:6;;28400:15;;28417:9:::1;-1:-1:-1::0;;;;;28417:17:93::1;::::0;::::1;::::0;841:18:137;;28417:25:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28368:75;::::0;-1:-1:-1;;;;;;28368:75:93::1;::::0;;;;;;::::1;::::0;::::1;19703:25:137::0;;;;19744:18;;;19737:34;;;;-1:-1:-1;;;;;19807:32:137;19787:18;;;19780:60;19676:18;;28368:75:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;28364:382:::0;27853:899:::1;;2303:20:46::0;1716:1;2809:7;:22;2629:209;45557:147:93;45631:4;45654:43;45673:5;45680:16;45654:18;:43::i;41845:347::-;41930:7;42019:16;2346:199;42149:9;42138:21;;;;;;;;:::i;:::-;;;;-1:-1:-1;;42138:21:93;;;;;;;;;;42059:114;;;42138:21;42059:114;;:::i;:::-;;;;;;;;;;;;;42049:125;;;;;;41966:218;;;;;;;;-1:-1:-1;;;20473:27:137;;20525:1;20516:11;;20509:27;;;;20561:2;20552:12;;20545:28;20598:2;20589:12;;20215:392;41966:218:93;;;;;;;;;;;;;41956:229;;;;;;41949:236;;41845:347;;;:::o;14272:3571::-;14483:14;2261:21:46;:19;:21::i;:::-;-1:-1:-1;;;;;14558:3:93::1;:10;;14569:29;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;14558:67;::::0;-1:-1:-1;;;;;;14558:67:93::1;::::0;;;;;;-1:-1:-1;;;;;15703:32:137;;;14558:67:93::1;::::0;::::1;15685:51:137::0;422:30:82::1;15752:18:137::0;;;15745:34;15658:18;;14558:67:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14553:198;;14677:29;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;14648:92;::::0;-1:-1:-1;;;14648:92:93;;-1:-1:-1;;;;;15703:32:137;;;14648:92:93::1;::::0;::::1;15685:51:137::0;422:30:82::1;15752:18:137::0;;;15745:34;15658:18;;14648:92:93::1;15511:274:137::0;14553:198:93::1;14799:22;::::0;;;::::1;::::0;::::1;;:::i;:::-;14795:107;;;14874:16;14837:54:::0;;-1:-1:-1;;;14837:54:93;;14862:10:::1;14837:54;::::0;::::1;15685:51:137::0;14874:16:93;;::::1;;15752:18:137::0;;;15745:34;14837:12:93::1;-1:-1:-1::0;;;;;14837:24:93::1;::::0;::::1;::::0;15658:18:137;;14837:54:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;14795:107;14991:28:::0;::::1;:33:::0;14987:295:::1;;15066:28:::0;::::1;15040:17;15060:35:::0;;;:5:::1;:35;::::0;;;;;;;15131:11;;15144:21;;::::1;::::0;15060:35;;15109:57:::1;::::0;15131:11:::1;::::0;;::::1;::::0;-1:-1:-1;;;15144:21:93;::::1;;;15109;:57::i;:::-;15224:47;15242:28:::0;::::1;15224:17;:47::i;:::-;15026:256;14987:295;15339:20;::::0;15409:29:::1;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;-1:-1:-1::0;;;;;15387:80:93::1;;15496:10;15543:28:::0;::::1;15603:25;;::::0;::::1;:12:::0;:25:::1;:::i;:::-;15670:35;;::::0;::::1;:12:::0;:35:::1;:::i;:::-;15734:12;:22;;;;;;;;:::i;:::-;15387:384;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15854:16:::0;;15338:433;;-1:-1:-1;15854:16:93;-1:-1:-1;;;;;;15840:30:93::1;:10;:30;::::0;::::1;::::0;:91:::1;;;15902:29;15920:10;15902:17;:29::i;:::-;15874:9;:24;;;:57;;15840:91;15836:230;;;15987:9;:24;;;16023:29;16041:10;16023:17;:29::i;:::-;15954:101;::::0;-1:-1:-1;;;15954:101:93;;::::1;::::0;::::1;25835:25:137::0;;;;25876:18;;;25869:34;25808:18;;15954:101:93::1;25661:248:137::0;15836:230:93::1;1778:10;16119:38;;:9;:18;;;:38;;;16115:150;;;16207:18;::::0;;::::1;::::0;16180:74;;-1:-1:-1;;;16180:74:93;;26096:10:137;26133:15;;;16180:74:93::1;::::0;::::1;26115:34:137::0;1778:10:93::1;26165:18:137::0;;;26158:43;26059:18;;16180:74:93::1;25914:293:137::0;16115:150:93::1;1845:4;16326:57;;:9;:29;;;:57;;;16322:195;;;16440:29;::::0;::::1;::::0;16406:100:::1;::::0;-1:-1:-1;;;16406:100:93;;26414:8:137;26402:21;;;16406:100:93::1;::::0;::::1;26384:40:137::0;1845:4:93::1;26440:18:137::0;;;26433:53;26357:18;;16406:100:93::1;26212:280:137::0;16322:195:93::1;16531:28:::0;::::1;;:33:::0;16527:345:::1;;16637:34;16654:9;:16;;;16637;:34::i;:::-;16685:38;16702:9;:20;;;16685:16;:38::i;:::-;16527:345;;;16796:65;16821:28:::0;::::1;16851:9:::0;16796:24:::1;:65::i;:::-;16920:93;16957:9;16992:10;16920:11;:93::i;:::-;16911:102:::0;-1:-1:-1;17141:29:93::1;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;-1:-1:-1::0;;;;;17029:305:93::1;17097:12;17063:6;17029:305;17203:10;:28;;;17252:9;17287:10;17318:5;;17029:305;;;;;;;;;;:::i;:::-;;;;;;;;17376:28:::0;::::1;;:33:::0;17372:465:::1;;17492:37;17507:9;17518:10;17492:14;:37::i;:::-;17372:465;;;17647:179;17705:28:::0;::::1;17762:9:::0;17801:10;17647:20:::1;:179::i;:::-;14499:3344;;2303:20:46::0;1716:1;2809:7;:22;2629:209;33581:2191:93;33689:10;33711:4;33689:27;33685:68;;33737:16;;-1:-1:-1;;;33737:16:93;;;;;;;;;;;33685:68;33764:17;33784:13;;;:5;:13;;;;;33856:11;;;;33871:1;33856:16;33852:56;;33893:15;;-1:-1:-1;;;33893:15:93;;;;;;;;;;;33852:56;34039:19;;;;-1:-1:-1;;;;;34039:32:93;;;:19;;:32;34035:79;;34092:22;;-1:-1:-1;;;34092:22:93;;;;;;;;;;;34035:79;34225:26;;;;34303:18;;-1:-1:-1;;;;;34225:26:93;;;;34196;;34303:38;;34225:26;34303:18;;;;34328:12;34303:24;:38::i;:::-;34261:80;;34427:19;34439:6;34427:11;:19::i;:::-;34462:49;;34503:5;;34484:6;;34462:49;;34503:5;;34462:49;34575:12;34591:1;34575:17;34571:42;;34606:7;;;33581:2191;;;:::o;34571:42::-;34786:9;-1:-1:-1;;;;;34764:31:93;:18;-1:-1:-1;;;;;34764:31:93;;34760:759;;34811:33;34817:15;34834:9;34811:5;:33::i;:::-;34760:759;;;34902:41;;-1:-1:-1;;;34902:41:93;;-1:-1:-1;;;;;678:32:137;;;34902:41:93;;;660:51:137;34875:24:93;;34902:6;:21;;;;;;633:18:137;;34902:41:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34875:68;-1:-1:-1;;;;;;35015:34:93;;35011:348;;35285:59;;-1:-1:-1;;;35285:59:93;;-1:-1:-1;;;;;678:32:137;;35285:59:93;;;660:51:137;633:18;;35285:59:93;497:220:137;35011:348:93;35434:74;35448:15;35465:11;35478:18;35498:9;35434:13;:74::i;:::-;34861:658;34760:759;33675:2097;;;33581:2191;;;:::o;2047:114::-;2107:48;1997:7;1946:3;2107:48;:::i;:::-;:54;;2158:3;2107:54;:::i;:::-;2047:114;:::o;10676:295:102:-;10910:6;10935:29;;-1:-1:-1;;;10935:29:102;;;;;;;;;;;13449:146:93;13529:7;13576:10;13565:22;;;;;;;;:::i;9782:366:102:-;9983:6;-1:-1:-1;;;;;10005:25:102;;10025:4;10005:25;10001:79;;10051:29;;-1:-1:-1;;;10051:29:102;;;;;;;;;;;10001:79;-1:-1:-1;;;;9782:366:102;;;;;;;;:::o;46923:887:93:-;47009:7;47048:14;;;:5;:14;;;;;47077:11;;;;:16;;47073:51;;-1:-1:-1;47122:1:93;;46923:887;-1:-1:-1;;46923:887:93:o;47073:51::-;47658:23;47673:7;47658:14;:23::i;:::-;47695:21;;;;47730:24;;;;47768;;;;47634:168;;;29204:4:137;29192:17;;;47634:168:93;;;29174:36:137;-1:-1:-1;;;47695:21:93;;;;;29226:18:137;;;29219:53;;;;29288:18;;;29281:34;-1:-1:-1;;;47768:24:93;;;;29331:18:137;;;29324:49;29146:19;;47634:168:93;;;;;;;;;;;;47624:179;;;;;;47617:186;;;46923:887;;;:::o;2336:287:46:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:46;;29586:2:137;2460:63:46;;;29568:21:137;29625:2;29605:18;;;29598:30;29664:33;29644:18;;;29637:61;29715:18;;2460:63:46;29384:355:137;2460:63:46;1759:1;2598:7;:18;2336:287::o;35997:599:93:-;36092:17;36112:13;;;:5;:13;;;;;;36220:9;:107;;36274:53;36299:27;36319:6;36299:19;:27::i;:::-;36274:18;;;;;-1:-1:-1;;;;;36274:18:93;;:24;:53::i;:::-;36220:107;;;;;;;;;;;;36244:15;;;36220:107;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;36220:107:93;;;;;;;;;;;;;;;;;;;;;;;;36188:139;;36413:19;36425:6;36413:11;:19::i;:::-;36448:53;;;;;;36470:6;;36448:53;;;;;36566:23;36572:5;36579:9;36566:5;:23::i;:::-;36082:514;;35997:599;;;:::o;1541:1696:92:-;1677:4;-1:-1:-1;;;;;1759:18:92;;;:22;1755:1476;;1798:12;1812:19;1835:6;-1:-1:-1;;;;;1835:17:92;1893:34;;;1929:4;1935:9;1870:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1870:75:92;;;;;;;;;;;;;;-1:-1:-1;;;;;1870:75:92;-1:-1:-1;;;;;;1870:75:92;;;;;;;;;;1835:124;;;;1870:75;1835:124;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1797:162;;;;1996:7;:46;;;;;2023:6;:13;2040:2;2023:19;1996:46;:142;;;;-1:-1:-1;2062:29:92;;-1:-1:-1;;;2103:34:92;2062:29;;;;;;;;;;;;:::i;:::-;:76;1996:142;1973:165;;;;;;1755:1476;2226:9;2249;2272:7;2348:9;:16;2368:2;2348:22;2344:817;;-1:-1:-1;;;2447:4:92;2432:20;;2426:27;2500:4;2485:20;;2479:27;2561:4;2546:20;;2540:27;2537:1;2532:36;2344:817;;;2686:9;:16;2706:2;2686:22;2682:479;;2814:4;2799:20;;2793:27;2868:4;2853:20;;2847:27;2793;;-1:-1:-1;;;;;;2914:80:92;;;-1:-1:-1;3022:25:92;3038:3;3023:18;;;3045:2;3022:25;:::i;:::-;3012:36;;2710:353;2682:479;;;3127:9;:16;3094:52;;-1:-1:-1;;;3094:52:92;;;;;;868:25:137;;856:2;841:18;;722:177;2682:479:92;3192:28;3206:4;3212:1;3215;3218;3192:13;:28::i;:::-;-1:-1:-1;;;;;3182:38:92;:6;-1:-1:-1;;;;;3182:38:92;;3175:45;;;;;1541:1696;;;;;:::o;2542:160:0:-;2618:12;;:::i;:::-;-1:-1:-1;2649:46:0;;;;;;;;-1:-1:-1;2649:46:0;;;-1:-1:-1;;;;;2649:46:0;;;;;;;;;;;;;;;;;;;;2542:160::o;45925:341:93:-;46010:19;46023:5;46010:12;:19::i;:::-;46005:255;;46109:14;;46103:21;;;;;;;;:::i;:::-;46148:18;;;;46188:8;;;;;46222:12;;;;46052:197;;-1:-1:-1;;;46052:197:93;;30776:4:137;30764:17;;;46052:197:93;;;30746:36:137;-1:-1:-1;;;;;30818:32:137;;;30798:18;;;30791:60;30867:18;;;30860:34;;;;30910:18;;;30903:34;30718:19;;46052:197:93;30519:424:137;4842:515:102;4948:23;4974:28;:5;4990:11;4974:15;:28::i;:::-;4948:54;-1:-1:-1;5013:48:102;:5;5041:6;5049:11;5013:27;:48::i;:::-;5071:222;5107:5;5143:15;5188:11;5234:6;5278:4;5071:14;:222::i;:::-;5338:11;-1:-1:-1;;;;;5309:41:102;5330:6;-1:-1:-1;;;;;5309:41:102;;5323:5;5309:41;;;;;;:::i;:::-;;;;;;;;4938:419;4842:515;;;:::o;31031:501:93:-;31125:24;;;;31102:7;;-1:-1:-1;;;31125:24:93;;;;:29;;31121:78;;-1:-1:-1;31175:24:93;;;;31031:501::o;31121:78::-;31255:19;;;;31210:23;;31278:9;;31237:37;;-1:-1:-1;;;31255:19:93;;;;31237:15;:37;:::i;:::-;31236:51;;;;:::i;:::-;31348:20;;;;31378:24;;;;31210:77;;-1:-1:-1;31297:23:93;;31323:143;;31348:20;31370:51;;31210:77;;-1:-1:-1;;;31378:24:93;;;;31370:51;:::i;:::-;2107:48;1997:7;1946:3;2107:48;:::i;:::-;:54;;2158:3;2107:54;:::i;:::-;31323:11;:143::i;:::-;31297:169;;31510:15;31483:4;:24;;;:42;;;;:::i;:::-;31476:49;31031:501;-1:-1:-1;;;;31031:501:93:o;44874:216::-;44936:5;44973:13;;;:5;:13;;;;;45004:11;;;;45019:1;45004:16;:60;;;;-1:-1:-1;45024:21:93;;;;45049:15;-1:-1:-1;;;45024:21:93;;;;;:40;;45004:60;45003:80;;45072:11;;;;45003:80;;;45068:1;44996:87;44874:216;-1:-1:-1;;;44874:216:93:o;28978:488::-;29151:6;:11;;29161:1;29151:11;29147:53;;29183:17;;-1:-1:-1;;;29183:17:93;;;;;;;;;;;29147:53;29252:6;:11;;29262:1;29252:11;29248:52;;29284:16;;-1:-1:-1;;;29284:16:93;;;;;;;;;;;29248:52;29378:15;29358:16;:35;;;29354:105;;29414:45;;-1:-1:-1;;;29414:45:93;;12647:12:137;12635:25;;29414:45:93;;;12617:44:137;12590:18;;29414:45:93;12473:194:137;29354:105:93;28978:488;;:::o;29588:592::-;29649:17;29669:13;;;:5;:13;;;;;29785:15;;-1:-1:-1;;29785:15:93;29799:1;29785:15;;;29880:26;29669:13;29880:20;:26::i;:::-;29853:24;;;:53;29916:24;;;:28;;-1:-1:-1;;;;29916:28:93;;;30141:32;;30164:6;;30141:32;;29943:1;;30141:32;29639:541;29588:592;:::o;3076:475:102:-;3157:23;3183:30;:5;3207:4;3183:15;:30::i;:::-;3157:56;-1:-1:-1;3224:46:102;:5;3248:6;3264:4;3224:23;:46::i;:::-;3280:224;3316:5;3352:15;3405:4;3445:6;3489:4;3280:14;:224::i;:::-;3537:6;-1:-1:-1;;;;;3520:24:102;;3530:5;3520:24;;;;;;:::i;:::-;;;;;;;;3147:404;3076:475;;:::o;3922:497::-;4008:23;4034:28;:5;4050:11;4034:15;:28::i;:::-;4008:54;-1:-1:-1;4073:55:102;:5;4109:4;4116:11;4073:27;:55::i;:::-;4138:229;4174:5;4210:15;4255:11;4309:4;4352;4138:14;:229::i;:::-;4400:11;-1:-1:-1;;;;;4383:29:102;;4393:5;4383:29;;;;;;:::i;17070:182:0:-;17168:4;17191:31;17206:5;17213:8;17191:14;:31::i;:::-;:54;;;;;17226:19;17239:5;17226:12;:19::i;18111:1230:93:-;18208:17;18228:13;;;:5;:13;;;;;;;;18513:16;;;;:29;;;;18491:18;;;;;-1:-1:-1;;;;;18491:18:93;;;:51;;;;;:95;;-1:-1:-1;18558:16:93;;;;:23;;;:28;18491:95;18474:155;;;18604:25;;-1:-1:-1;;;18604:25:93;;;;;;;;;;;18474:155;18755:20;;;;:29;18727:57;;;;;;;;:::i;:::-;:15;;;:24;;;:57;;;;;;;;:::i;:::-;;;:138;;;-1:-1:-1;18832:20:93;;;;:33;;;18800:15;;;:28;;;;-1:-1:-1;;;;;18800:28:93;;;:65;;;;18727:138;:199;;;-1:-1:-1;18903:20:93;;;;:23;;;18881:18;;;;:45;;18727:199;:268;;;-1:-1:-1;18968:20:93;;;;;:27;;18942:22;;;;:53;;18727:268;18710:332;;;19013:29;;-1:-1:-1;;;19013:29:93;;;;;;;;;;;18710:332;19145:18;;;;19128:13;;;;-1:-1:-1;;;;;19128:13:93;;;:35;;;19124:211;;19247:13;;;;19291:18;;;;19186:138;;-1:-1:-1;;;19186:138:93;;-1:-1:-1;;;;;19247:13:93;;;19186:138;;;17355:34:137;17425:15;;17405:18;;;17398:43;17290:18;;19186:138:93;17143:304:137;19526:922:93;19730:16;;19715:32;;-1:-1:-1;;;19715:32:93;;-1:-1:-1;;;;;678:32:137;;;19715::93;;;660:51:137;19642:14:93;;19715:9;:14;;;;633:18:137;;19715:32:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19799:17;19819:13;;;:5;:13;;;;;;;;19842:15;;19888:16;;;;:29;;;-1:-1:-1;;;;;19867:50:93;19842:15;19867:50;-1:-1:-1;;;;;;19867:50:93;;;;19856:1;19867:50;;;19706:41;;-1:-1:-1;19956:24:93;;;;:10;:24;:::i;:::-;19927:26;;;:53;;19990:45;20019:15;19990:45;;;-1:-1:-1;;;19990:45:93;-1:-1:-1;;;;;;19990:45:93;;;-1:-1:-1;;;;;19927:53:93;;;;19990:45;;;;;;;20095:18;;;;20069:44;;;;;;;;:::i;:::-;20045:21;;;;:68;;;;;;;-1:-1:-1;;;20045:68:93;-1:-1:-1;;;;20045:68:93;;;;;;;;;;20139:18;;;;20123:13;;;:34;;-1:-1:-1;;;;;20123:34:93;;;-1:-1:-1;;;;;;20123:34:93;;;;;;20189:16;;20167:19;;;;:38;;20242:29;;;;20215:56;;-1:-1:-1;;;20215:56:93;-1:-1:-1;;;;;;20215:56:93;;;20167:38;;;;20215:56;;;;;;;;;;20308:29;;;;20281:24;;;:56;20370:16;;;;:23;;;;;20347:20;;;:46;20421:20;;;20403:38;;:15;;;:38;;20421:20;;20403:15;;:38;;:15;;-1:-1:-1;;20403:38:93;;;;20045:21;20403:38;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;20403:38:93;;;;;;-1:-1:-1;;;;;20403:38:93;;;;;-1:-1:-1;;;;;;20403:38:93;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19526:922:93;;-1:-1:-1;;19526:922:93:o;20660:1145::-;20820:47;20826:9;:20;;;20848:9;:18;;;20820:5;:47::i;:::-;20955:16;;-1:-1:-1;;;;;20927:44:93;:24;;;;:10;:24;:::i;:::-;-1:-1:-1;;;;;20927:44:93;;20923:196;;21044:64;21068:9;:16;;;21086:9;21097:10;21044:23;:64::i;:::-;21182:17;21201:21;21238:74;21274:6;-1:-1:-1;;;;;21274:10:93;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21288:9;:16;;;:23;;;21238:35;:74::i;:::-;21439:16;;;;21181:131;;-1:-1:-1;21181:131:93;-1:-1:-1;21494:13:93;;21490:153;;21545:9;21523:12;:19;;:31;;;;;21568:64;21578:12;21592:9;:16;;;21610:6;-1:-1:-1;;;;;21610:19:93;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21568:9;:64::i;:::-;21692:19;;;:35;;;21761:16;;21779:18;;;;21737:61;;21692:12;;21737:9;:61::i;22367:3764::-;22528:17;22548:24;;;:5;:24;;;;;;22602:36;;-1:-1:-1;;;22602:36:93;;;;;868:25:137;;;22548:24:93;;22528:17;22602:9;-1:-1:-1;;;;;22602:17:93;;;;841:18:137;;22602:36:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22582:56;;22648:23;22674:38;22694:17;22674:19;:38::i;:::-;22648:64;;22776:17;22795:21;22832:74;22868:6;-1:-1:-1;;;;;22868:10:93;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22882:9;:16;;;:23;;;22832:35;:74::i;:::-;22775:131;;;;22917:14;22934:40;22943:15;22960:13;22934:8;:40::i;:::-;22917:57;;22984:15;23018;23002:13;:31;:69;;23070:1;23002:69;;;23036:31;23052:15;23036:13;:31;:::i;:::-;22984:87;;23081:16;23110:1;23100:7;:11;:49;;23118:31;23136:13;23118:15;:31;:::i;:::-;23100:49;;;23114:1;23100:49;23081:68;;23468:25;23528:9;-1:-1:-1;;;;;23508:29:93;:9;:16;;;-1:-1:-1;;;;;23508:29:93;;;:137;;;-1:-1:-1;23554:19:93;;;;-1:-1:-1;;;;;23554:32:93;;;:19;;:32;:90;;;;-1:-1:-1;23620:24:93;;;;:10;:24;:::i;:::-;23590:26;;;;-1:-1:-1;;;;;23590:26:93;;;:54;;;;23554:90;23772:16;;;;23876;;23468:177;;-1:-1:-1;23772:16:93;-1:-1:-1;;;;;23848:44:93;:24;;;;:10;:24;:::i;:::-;-1:-1:-1;;;;;23848:44:93;;23844:285;;24037:7;24000:20;:33;;24032:1;24000:33;;;24023:6;24000:33;23987:47;;:9;:47;:::i;:::-;:57;;;;:::i;:::-;23965:19;;;:79;24058:60;23965:12;24096:9;24107:10;24058:23;:60::i;:::-;24167:13;;24163:153;;24218:9;24196:12;:19;;:31;;;;;24241:64;24251:12;24265:9;:16;;;24283:6;-1:-1:-1;;;;;24283:19:93;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24241:64;24390:20;24386:130;;;24426:19;;;:28;;;24488:16;;24468:37;;24426:12;;24468:5;:37::i;:::-;24576:11;;24572:459;;24692:19;;;:29;;;24759:16;;24777:18;;;;24735:61;;24692:12;;24735:9;:61::i;:::-;24572:459;;;24817:12;;24813:218;;24937:19;;;:30;;;25001:18;;;;24981:39;;24937:12;;24981:5;:39::i;:::-;25078:4;:23;25124:17;25207:8;25170:20;:33;;25202:1;25170:33;;;25193:6;25170:33;25169:46;;;;:::i;:::-;25078:182;;-1:-1:-1;;;;;;25078:182:93;;;;;;;;;;19703:25:137;;;;19744:18;;;19737:34;-1:-1:-1;;;;;19807:32:137;;19787:18;;;19780:60;19676:18;;25078:182:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25074:1051;;25687:20;25682:433;;25727:19;;;:28;;;25805:16;;-1:-1:-1;;;;;25777:44:93;:24;;;;:10;:24;:::i;:::-;-1:-1:-1;;;;;25777:44:93;;25773:273;;25967:60;25991:12;26005:9;26016:10;25967:23;:60::i;:::-;26063:37;26069:12;26083:9;:16;;;26063:5;:37::i;:::-;22518:3613;;;;;;;;;;22367:3764;;;:::o;36728:114::-;36783:22;;-1:-1:-1;;;36783:22:93;;;;;868:25:137;;;36783:9:93;-1:-1:-1;;;;;36783:14:93;;;;841:18:137;;36783:22:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;36822:13:93;;;;-1:-1:-1;36822:5:93;:13;;;;;;;36815:20;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36728:114::o;6865:714:102:-;6993:23;7019:30;:5;7043:4;7019:15;:30::i;:::-;6993:56;-1:-1:-1;7060:60:102;:5;7092:4;7107:11;7060:23;:60::i;:::-;7162:18;;;;7182:12;;;;7130:65;;-1:-1:-1;;;7130:65:102;;-1:-1:-1;;;;;32434:15:137;;;7130:65:102;;;32416:34:137;32486:15;;;32466:18;;;32459:43;32538:15;;;32518:18;;;32511:43;32570:18;;;32563:34;;;;7130:18:102;;;;;;32350:19:137;;7130:65:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7205:223;7241:5;7277:15;7330:4;7370;7412:5;7205:14;:223::i;:::-;7566:5;-1:-1:-1;;;;;7520:52:102;7560:4;-1:-1:-1;;;;;7520:52:102;7546:11;-1:-1:-1;;;;;7520:52:102;;7531:5;7520:52;;;;;;:::i;:::-;;;;;;;;6983:596;6865:714;;;;:::o;6598:232:65:-;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:65;6598:232;-1:-1:-1;;;;;6598:232:65:o;14248:722:0:-;14326:7;;14349:14;;:32;;;;;;;;:::i;:::-;;14345:619;;14411:18;;;;14404:44;;-1:-1:-1;;;14404:44:0;;-1:-1:-1;;;;;678:32:137;;;14404:44:0;;;660:51:137;14404:36:0;;;;;;633:18:137;;14404:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14397:51;;;;14345:619;14488:15;14470:14;;:33;;;;;;;;:::i;:::-;;14466:498;;14575:6;-1:-1:-1;;;;;14526:55:0;14534:5;:18;;;-1:-1:-1;;;;;14526:35:0;;14562:5;:8;;;14526:45;;;;;;;;;;;;;868:25:137;;856:2;841:18;;722:177;14526:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14526:55:0;;:63;;14588:1;14526:63;;;14584:1;14526:63;14519:70;;;;;;14466:498;14629:16;14611:14;;:34;;;;;;;;:::i;:::-;;14607:357;;14677:18;;;;14715:8;;;;;14668:56;;-1:-1:-1;;;14668:56:0;;-1:-1:-1;;;;;15703:32:137;;;14668:56:0;;;15685:51:137;15752:18;;;15745:34;;;;14668:38:0;;;;;15658:18:137;;14668:56:0;15511:274:137;14607:357:0;14764:22;14746:14;;:40;;;;;;;;:::i;:::-;;14742:222;;14865:6;-1:-1:-1;;;;;14809:62:0;14824:5;:18;;;-1:-1:-1;;;;;14809:42:0;;14852:5;:8;;;14809:52;;;;;;;;;;;;;868:25:137;;856:2;841:18;;722:177;14742:222:0;14911:42;;-1:-1:-1;;;14911:42:0;;32810:2:137;14911:42:0;;;32792:21:137;;;32829:18;;;32822:30;32888:34;32868:18;;;32861:62;32940:18;;14911:42:0;32608:356:137;5635:152:0;5735:45;5754:5;5761:6;5769:4;5775;5735:18;:45::i;7585:668:102:-;7838:19;-1:-1:-1;;;;;7820:37:102;:14;-1:-1:-1;;;;;7820:37:102;;7816:138;;7880:63;;-1:-1:-1;;;7880:63:102;;-1:-1:-1;;;;;678:32:137;;7880:63:102;;;660:51:137;633:18;;7880:63:102;497:220:137;7816:138:102;7964:23;7990:22;:138;;8103:25;:5;:23;:25::i;:::-;8085:43;;:15;:43;:::i;:::-;7990:138;;;8045:25;:5;:23;:25::i;:::-;8027:43;;:15;:43;:::i;:::-;7964:164;-1:-1:-1;8162:31:102;:5;8178:14;8162:15;:31::i;:::-;8143:15;:50;8139:108;;8216:20;;-1:-1:-1;;;8216:20:102;;;;;;;;;;;1667:4213:70;1749:14;;;-1:-1:-1;;2286:1:70;2283;2276:20;2329:1;2326;2322:9;2313:18;;2384:5;2380:2;2377:13;2369:5;2365:2;2361:14;2357:34;2348:43;;;2486:5;2495:1;2486:10;2482:368;;2824:11;2816:5;:19;;;;;:::i;:::-;;2809:26;;;;;;2482:368;2974:5;2960:11;:19;2952:53;;;;-1:-1:-1;;;2952:53:70;;33171:2:137;2952:53:70;;;33153:21:137;33210:2;33190:18;;;33183:30;-1:-1:-1;;;33229:18:137;;;33222:51;33290:18;;2952:53:70;32969:345:137;2952:53:70;3261:17;3396:11;3393:1;3390;3383:25;4774:1;3944;3929:12;;:16;;3914:32;;4049:22;;;;4755:1;:15;;4754:21;;5007;;;5003:25;;4992:36;5076:21;;;5072:25;;5061:36;5146:21;;;5142:25;;5131:36;5216:21;;;5212:25;;5201:36;5286:21;;;5282:25;;5271:36;5357:21;;;5353:25;;;5342:36;;;3899:12;4294;;;4290:23;;;4286:31;;;3510:20;;;3499:32;;;4406:12;;;;3557:21;;4147:16;;;;4397:21;;;;5821:15;;;-1:-1:-1;;;;1667:4213:70:o;5077:149:0:-;5173:46;5192:5;5199:6;5207:4;5213:5;5173:18;:46::i;18426:428::-;18667:18;;;;18634:52;;-1:-1:-1;;;18634:52:0;;-1:-1:-1;;;;;678:32:137;;;18634:52:0;;;660:51:137;18531:4:0;;;;18634:32;;;;;;633:18:137;;18634:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18612:74;-1:-1:-1;1293:15:0;18700:40;;;;18696:103;;18767:14;;18761:38;;;;:21;;;;;;;;:::i;:::-;:38;;;18754:45;;;;;18696:103;18817:30;18841:5;18817:23;:30::i;21578:735::-;21643:4;;21663:14;;:32;;;;;;;;:::i;:::-;;21659:626;;21753:8;;;;:13;21749:31;;-1:-1:-1;21775:5:0;;21578:735;-1:-1:-1;21578:735:0:o;21749:31::-;21659:626;;;21820:15;21802:14;;:33;;;;;;;;:::i;:::-;;21798:487;;21898:12;;;;:17;21894:35;;-1:-1:-1;21924:5:0;;21578:735;-1:-1:-1;21578:735:0:o;21798:487::-;21969:16;21951:14;;:34;;;;;;;;:::i;:::-;21947:338;;;22070:22;22052:14;;:40;;;;;;;;:::i;:::-;;22048:237;;22162:12;;;;:17;22158:35;;-1:-1:-1;22188:5:0;;21578:735;-1:-1:-1;21578:735:0:o;22048:237::-;22258:14;;22252:21;;;;;;;;:::i;:::-;22232:42;;-1:-1:-1;;;22232:42:0;;33769:4:137;33757:17;;;22232:42:0;;;33739:36:137;33712:18;;22232:42:0;33597:184:137;22048:237:0;-1:-1:-1;22302:4:0;;21578:735;-1:-1:-1;21578:735:0:o;26453:536:93:-;26622:24;-1:-1:-1;;;;;26649:6:93;:21;;26671:24;;;;:10;:24;:::i;:::-;26649:47;;-1:-1:-1;;;;;;26649:47:93;;;;;;;-1:-1:-1;;;;;678:32:137;;;26649:47:93;;;660:51:137;633:18;;26649:47:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26622:74;-1:-1:-1;;;;;;26710:34:93;;26706:137;;26805:24;;;;:10;:24;:::i;:::-;26767:65;;-1:-1:-1;;;26767:65:93;;-1:-1:-1;;;;;678:32:137;;;26767:65:93;;;660:51:137;633:18;;26767:65:93;497:220:137;26706:137:93;26857:13;;;;:17;26853:130;;26890:82;26908:6;26916:11;26929:24;;;;:10;:24;:::i;:::-;26955:16;;26890:17;:82::i;:::-;26612:377;26453:536;;;:::o;671:294:91:-;754:17;773:21;810:3;:8;;817:1;810:8;806:48;;-1:-1:-1;840:1:91;;-1:-1:-1;843:10:91;832:22;;806:48;877:33;889:10;901:3;877:33;;906:3;877:11;:33::i;:::-;865:45;-1:-1:-1;936:22:91;865:45;936:10;:22;:::i;:::-;920:38;;671:294;;;;;;:::o;588:104:70:-;646:7;676:1;672;:5;:13;;684:1;672:13;;;-1:-1:-1;680:1:70;;588:104;-1:-1:-1;588:104:70:o;5009:1456:65:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:65;;-1:-1:-1;6123:30:65;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;34013:25:137;;;34086:4;34074:17;;34054:18;;;34047:45;;;;34108:18;;;34101:34;;;34151:18;;;34144:34;;;6276:24:65;;33985:19:137;;6276:24:65;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:65;;-1:-1:-1;;6276:24:65;;;-1:-1:-1;;;;;;;6314:20:65;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:65;;-1:-1:-1;5009:1456:65;;;;;;;;:::o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:65;;34391:2:137;788:34:65;;;34373:21:137;34430:2;34410:18;;;34403:30;34469:26;34449:18;;;34442:54;34513:18;;788:34:65;34189:348:137;730:345:65;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:65;;34744:2:137;903:41:65;;;34726:21:137;34783:2;34763:18;;;34756:30;34822:33;34802:18;;;34795:61;34873:18;;903:41:65;34542:355:137;839:236:65;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:65;;35104:2:137;1020:44:65;;;35086:21:137;35143:2;35123:18;;;35116:30;35182:34;35162:18;;;35155:62;-1:-1:-1;;;35233:18:137;;;35226:32;35275:19;;1020:44:65;34902:398:137;5793:1204:0;5924:14;5906;;:32;;;;;;;;:::i;:::-;;5902:1089;;5976:4;-1:-1:-1;;;;;5958:23:0;;;5954:210;;5999:59;6039:4;6045:5;:12;;;6006:5;:18;;;-1:-1:-1;;;;;5999:39:0;;;:59;;;;;:::i;:::-;5902:1089;;5954:210;6093:71;6137:6;6145:4;6151:5;:12;;;6100:5;:18;;;-1:-1:-1;;;;;6093:43:0;;;:71;;;;;;:::i;5902:1089::-;6204:15;6186:14;;:33;;;;;;;;:::i;:::-;;6182:809;;6240:6;6235:200;;6272:18;;;;6319:8;;;;;6264:64;;-1:-1:-1;;;6264:64:0;;-1:-1:-1;;;;;35563:15:137;;;6264:64:0;;;35545:34:137;35615:15;;;35595:18;;;35588:43;35647:18;;;35640:34;;;;6264:40:0;;;;;35480:18:137;;6264:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6182:809;;6235:200;6371:18;;;;6422:8;;;;;6363:72;;-1:-1:-1;;;6363:72:0;;-1:-1:-1;;;;;36008:15:137;;;6363:72:0;;;35990:34:137;36060:15;;;36040:18;;;36033:43;36092:18;;;36085:34;;;;36155:3;36135:18;;;36128:31;-1:-1:-1;36175:19:137;;;36168:30;6363:44:0;;;;;36215:19:137;;6363:72:0;35685:555:137;6182:809:0;6475:16;6457:14;;:34;;;;;;;;:::i;:::-;;6453:538;;6516:5;:18;;;-1:-1:-1;;;;;6507:45:0;;6553:6;6561:4;6567:5;:8;;;6577:5;:12;;;6593:1;6577:17;:36;;6601:5;:12;;;6577:36;;;6597:1;6577:36;6507:111;;-1:-1:-1;;;;;;6507:111:0;;;;;;;-1:-1:-1;;;;;36596:15:137;;;6507:111:0;;;36578:34:137;36648:15;;;;36628:18;;;36621:43;36680:18;;;36673:34;36723:18;;;36716:34;36558:3;36766:19;;;36759:32;-1:-1:-1;36807:19:137;;;36800:30;36847:19;;6507:111:0;36245:627:137;6453:538:0;6658:22;6640:14;;:40;;;;;;;;:::i;:::-;;6636:355;;6718:4;-1:-1:-1;;;;;6700:23:0;;;6696:210;;6756:18;;;;6791:8;;;;;6741:59;;-1:-1:-1;;;6741:59:0;;-1:-1:-1;;;;;15703:32:137;;;6741:59:0;;;15685:51:137;15752:18;;;15745:34;;;;6741:43:0;;;;;15658:18:137;;6741:59:0;15511:274:137;6696:210:0;6850:18;;;;6897:8;;;;;6835:71;;-1:-1:-1;;;6835:71:0;;-1:-1:-1;;;;;35563:15:137;;;6835:71:0;;;35545:34:137;35615:15;;;35595:18;;;35588:43;35647:18;;;35640:34;;;;6835:47:0;;;;;35480:18:137;;6835:71:0;35305:375:137;7478:382:0;7548:7;;7571:14;;:32;;;;;;;;:::i;:::-;;7567:286;;-1:-1:-1;7624:12:0;;;;7478:382::o;7567:286::-;7673:16;7655:14;;:34;;;;;;;;:::i;:::-;;:54;;;;;7708:1;7693:5;:12;;;:16;7655:54;7651:202;;;-1:-1:-1;7730:12:0;;;;7478:382::o;7651:202::-;7478:382;;;:::o;19179:2028::-;19255:4;;19275:14;;:32;;;;;;;;:::i;:::-;;19271:1930;;19383:35;:5;:18;;;-1:-1:-1;;;;;19383:33:0;;:35::i;:::-;19379:1184;;;19563:18;;;;:71;;-1:-1:-1;;;;;19563:51:0;-1:-1:-1;;;19563:51:0;:71::i;:::-;19559:108;;;-1:-1:-1;19663:4:0;;19179:2028;-1:-1:-1;19179:2028:0:o;19559:108::-;19840:18;;;;:72;;-1:-1:-1;;;;;19840:51:0;-1:-1:-1;;;19840:51:0;:72::i;:::-;19839:73;:171;;;;-1:-1:-1;19937:18:0;;;;:73;;-1:-1:-1;;;;;19937:51:0;-1:-1:-1;;;19937:51:0;:73::i;:::-;19936:74;19839:171;:276;;;;-1:-1:-1;20035:18:0;;;;:80;;-1:-1:-1;;;;;20035:51:0;-1:-1:-1;;;20035:51:0;:80::i;:::-;20034:81;19812:303;19179:2028;-1:-1:-1;;19179:2028:0:o;19379:1184::-;-1:-1:-1;20514:18:0;;;-1:-1:-1;;;;;20514:30:0;;:34;;;19179:2028::o;19271:1930::-;20602:15;20584:14;;:33;;;;;;;;:::i;:::-;;20580:621;;20679:18;;;;:57;;-1:-1:-1;;;;;20679:36:0;-1:-1:-1;;;20679:36:0;:57::i;20580:621::-;20776:16;20758:14;;:34;;;;;;;;:::i;:::-;;20754:447;;20855:18;;;;:58;;-1:-1:-1;;;;;20855:36:0;-1:-1:-1;;;20855:36:0;:58::i;20754:447::-;20953:22;20935:14;;:40;;;;;;;;:::i;:::-;;20931:270;;21044:18;;;;:65;;-1:-1:-1;;;;;21044:36:0;-1:-1:-1;;;21044:36:0;:65::i;5795:559:102:-;5927:23;5953:22;:5;5969;5953:15;:22::i;:::-;6020:18;;;;6040:12;;;;5986:67;;-1:-1:-1;;;5986:67:102;;-1:-1:-1;;;;;32434:15:137;;;5986:67:102;;;32416:34:137;32486:15;;;32466:18;;;32459:43;32538:15;;;32518:18;;;32511:43;32570:18;;;32563:34;;;;5927:48:102;;-1:-1:-1;5986:20:102;;;;;32350:19:137;;5986:67:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6063:214;6099:5;6135:15;6180:5;6220:4;6262;6063:14;:214::i;:::-;6341:5;-1:-1:-1;;;;;6293:54:102;6335:4;-1:-1:-1;;;;;6293:54:102;6321:11;-1:-1:-1;;;;;6293:54:102;;6306:5;6293:54;;;;;;:::i;941:175:55:-;1050:58;;-1:-1:-1;;;;;15703:32:137;;1050:58:55;;;15685:51:137;15752:18;;;15745:34;;;1023:86:55;;1043:5;;-1:-1:-1;;;1073:23:55;15658:18:137;;1050:58:55;;;;-1:-1:-1;;1050:58:55;;;;;;;;;;;;;;-1:-1:-1;;;;;1050:58:55;-1:-1:-1;;;;;;1050:58:55;;;;;;;;;;1023:19;:86::i;1355:203::-;1482:68;;-1:-1:-1;;;;;35563:15:137;;;1482:68:55;;;35545:34:137;35615:15;;35595:18;;;35588:43;35647:18;;;35640:34;;;1455:96:55;;1475:5;;-1:-1:-1;;;1505:27:55;35480:18:137;;1482:68:55;35305:375:137;704:427:68;768:4;975:68;1008:7;-1:-1:-1;;;975:32:68;:68::i;:::-;:149;;;;-1:-1:-1;1060:64:68;1093:7;-1:-1:-1;;;;;;4421:647:68;4592:71;;;-1:-1:-1;;;;;;3254:33:137;;4592:71:68;;;;3236:52:137;;;;4592:71:68;;;;;;;;;;3209:18:137;;;;4592:71:68;;;;;;;;;-1:-1:-1;;;;;4592:71:68;-1:-1:-1;;;4592:71:68;;;4871:20;;4523:4;;4592:71;4523:4;;;;;;4592:71;4523:4;;4871:20;4836:7;4829:5;4818:86;4807:97;;4931:16;4917:30;;4981:4;4975:11;4960:26;;5013:7;:29;;;;;5038:4;5024:10;:18;;5013:29;:48;;;;;5060:1;5046:11;:15;5013:48;5006:55;4421:647;-1:-1:-1;;;;;;;4421:647:68:o;1349:282::-;1436:4;1543:23;1558:7;1543:14;:23::i;:::-;:81;;;;;1570:54;1603:7;1612:11;1570:32;:54::i;5196:642:55:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;-1:-1:-1;;;;;5641:27:55;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:55;;37079:2:137;5720:111:55;;;37061:21:137;37118:2;37098:18;;;37091:30;37157:34;37137:18;;;37130:62;-1:-1:-1;;;37208:18:137;;;37201:40;37258:19;;5720:111:55;36877:406:137;4108:223:60;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4241;5446;5460:23;5487:6;-1:-1:-1;;;;;5487:11:60;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;7851;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;-1:-1:-1;;;;;1702:19:60;;;8113:60;;;;-1:-1:-1;;;8113:60:60;;37897:2:137;8113:60:60;;;37879:21:137;37936:2;37916:18;;;37909:30;37975:31;37955:18;;;37948:59;38024:18;;8113:60:60;37695:353:137;8113:60:60;-1:-1:-1;8208:10:60;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:60;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:286:137:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:137;;209:43;;199:71;;266:1;263;256:12;904:180;963:6;1016:2;1004:9;995:7;991:23;987:32;984:52;;;1032:1;1029;1022:12;984:52;-1:-1:-1;1055:23:137;;904:180;-1:-1:-1;904:180:137:o;1089:250::-;1174:1;1184:113;1198:6;1195:1;1192:13;1184:113;;;1274:11;;;1268:18;1255:11;;;1248:39;1220:2;1213:10;1184:113;;;-1:-1:-1;;1331:1:137;1313:16;;1306:27;1089:250::o;1344:271::-;1386:3;1424:5;1418:12;1451:6;1446:3;1439:19;1467:76;1536:6;1529:4;1524:3;1520:14;1513:4;1506:5;1502:16;1467:76;:::i;:::-;1597:2;1576:15;-1:-1:-1;;1572:29:137;1563:39;;;;1604:4;1559:50;;1344:271;-1:-1:-1;;1344:271:137:o;1620:220::-;1769:2;1758:9;1751:21;1732:4;1789:45;1830:2;1819:9;1815:18;1807:6;1789:45;:::i;1845:131::-;-1:-1:-1;;;;;1920:31:137;;1910:42;;1900:70;;1966:1;1963;1956:12;1981:347;2032:8;2042:6;2096:3;2089:4;2081:6;2077:17;2073:27;2063:55;;2114:1;2111;2104:12;2063:55;-1:-1:-1;2137:20:137;;-1:-1:-1;;;;;2169:30:137;;2166:50;;;2212:1;2209;2202:12;2166:50;2249:4;2241:6;2237:17;2225:29;;2301:3;2294:4;2285:6;2277;2273:19;2269:30;2266:39;2263:59;;;2318:1;2315;2308:12;2333:754;2430:6;2438;2446;2454;2462;2515:3;2503:9;2494:7;2490:23;2486:33;2483:53;;;2532:1;2529;2522:12;2483:53;2571:9;2558:23;2590:31;2615:5;2590:31;:::i;:::-;2640:5;-1:-1:-1;2697:2:137;2682:18;;2669:32;2710:33;2669:32;2710:33;:::i;:::-;2762:7;-1:-1:-1;2816:2:137;2801:18;;2788:32;;-1:-1:-1;2871:2:137;2856:18;;2843:32;-1:-1:-1;;;;;2887:30:137;;2884:50;;;2930:1;2927;2920:12;2884:50;2969:58;3019:7;3010:6;2999:9;2995:22;2969:58;:::i;:::-;2333:754;;;;-1:-1:-1;2333:754:137;;-1:-1:-1;3046:8:137;;2943:84;2333:754;-1:-1:-1;;;2333:754:137:o;3299:166::-;3369:5;3414:3;3405:6;3400:3;3396:16;3392:26;3389:46;;;3431:1;3428;3421:12;3389:46;-1:-1:-1;3453:6:137;3299:166;-1:-1:-1;3299:166:137:o;3470:558::-;3587:6;3595;3603;3656:3;3644:9;3635:7;3631:23;3627:33;3624:53;;;3673:1;3670;3663:12;3624:53;3696:64;3752:7;3741:9;3696:64;:::i;:::-;3686:74;;3811:3;3800:9;3796:19;3783:33;-1:-1:-1;;;;;3831:6:137;3828:30;3825:50;;;3871:1;3868;3861:12;3825:50;3910:58;3960:7;3951:6;3940:9;3936:22;3910:58;:::i;:::-;3470:558;;3987:8;;-1:-1:-1;3884:84:137;;-1:-1:-1;;;;3470:558:137:o;4439:260::-;4536:6;4589:3;4577:9;4568:7;4564:23;4560:33;4557:53;;;4606:1;4603;4596:12;4557:53;4629:64;4685:7;4674:9;4629:64;:::i;4910:127::-;4971:10;4966:3;4962:20;4959:1;4952:31;5002:4;4999:1;4992:15;5026:4;5023:1;5016:15;5042:454;5117:5;5111:12;5149:1;5145:2;5142:9;5132:140;;5194:10;5189:3;5185:20;5182:1;5175:31;5229:4;5226:1;5219:15;5257:4;5254:1;5247:15;5132:140;5281:15;;5349:4;5338:16;;;5332:23;-1:-1:-1;;;;;5328:49:137;5312:14;;;5305:73;5427:4;5416:16;;;5410:23;5394:14;;;5387:47;5483:4;5472:16;;;5466:23;5450:14;;5443:47;5042:454::o;5501:1231::-;6062:4;6050:17;;6032:36;;6087:12;6135:15;;;6130:2;6115:18;;6108:43;6187:15;;6182:2;6167:18;;6160:43;-1:-1:-1;;;;;6277:15:137;;;6272:2;6257:18;;6250:43;6330:15;;;6324:3;6309:19;;6302:44;6383:15;;6230:3;6362:19;;6355:44;6448:8;6436:21;;6430:3;6415:19;;6408:50;6489:3;6474:19;;6467:35;;;6019:3;6004:19;;6511:52;6558:3;6543:19;;6535:6;6511:52;:::i;:::-;6572;6619:3;6608:9;6604:19;6596:6;6572:52;:::i;:::-;-1:-1:-1;;;;;4770:31:137;;;;6676:3;6661:19;;4758:44;6712:3;6697:19;6690:36;5501:1231;;-1:-1:-1;;;;;;;;;;5501:1231:137:o;7166:127::-;7227:10;7222:3;7218:20;7215:1;7208:31;7258:4;7255:1;7248:15;7282:4;7279:1;7272:15;7298:250;7365:2;7359:9;7407:6;7395:19;;-1:-1:-1;;;;;7429:34:137;;7465:22;;;7426:62;7423:88;;;7491:18;;:::i;:::-;7527:2;7520:22;7298:250;:::o;7553:107::-;7634:1;7627:5;7624:12;7614:40;;7650:1;7647;7640:12;7665:780;7745:6;7798:3;7786:9;7777:7;7773:23;7769:33;7766:53;;;7815:1;7812;7805:12;7766:53;7848:2;7842:9;7890:3;7882:6;7878:16;7960:6;7948:10;7945:22;-1:-1:-1;;;;;7912:10:137;7909:34;7906:62;7903:88;;;7971:18;;:::i;:::-;8007:2;8000:22;8044:23;;8076:37;8044:23;8076:37;:::i;:::-;8122:21;;8195:2;8180:18;;8167:32;8208:33;8167:32;8208:33;:::i;:::-;8269:2;8257:15;;8250:32;8343:2;8328:18;;;8315:32;8298:15;;;8291:57;8409:2;8394:18;;;8381:32;8364:15;;;8357:57;;;;-1:-1:-1;8261:6:137;7665:780;-1:-1:-1;7665:780:137:o;8450:158::-;8513:5;8558:2;8549:6;8544:3;8540:16;8536:25;8533:45;;;8574:1;8571;8564:12;8613:996;8805:6;8813;8821;8829;8837;8881:9;8872:7;8868:23;8911:3;8907:2;8903:12;8900:32;;;8928:1;8925;8918:12;8900:32;8968:9;8955:23;-1:-1:-1;;;;;9038:2:137;9030:6;9027:14;9024:34;;;9054:1;9051;9044:12;9024:34;9077:22;;;;9133:3;9115:16;;;9111:26;9108:46;;;9150:1;9147;9140:12;9108:46;9173:2;9163:12;;9194:66;9252:7;9247:2;9236:9;9232:18;9194:66;:::i;:::-;9184:76;-1:-1:-1;9294:2:137;-1:-1:-1;;9276:16:137;;9272:25;9269:45;;;9310:1;9307;9300:12;9269:45;9348:2;9337:9;9333:18;9323:28;;9404:3;9393:9;9389:19;9376:33;9360:49;;9434:2;9424:8;9421:16;9418:36;;;9450:1;9447;9440:12;9418:36;;;9489:60;9541:7;9530:8;9519:9;9515:24;9489:60;:::i;10137:383::-;10214:6;10222;10230;10283:2;10271:9;10262:7;10258:23;10254:32;10251:52;;;10299:1;10296;10289:12;10251:52;10335:9;10322:23;10312:33;;10392:2;10381:9;10377:18;10364:32;10354:42;;10446:2;10435:9;10431:18;10418:32;10459:31;10484:5;10459:31;:::i;:::-;10509:5;10499:15;;;10137:383;;;;;:::o;10758:367::-;10821:8;10831:6;10885:3;10878:4;10870:6;10866:17;10862:27;10852:55;;10903:1;10900;10893:12;10852:55;-1:-1:-1;10926:20:137;;-1:-1:-1;;;;;10958:30:137;;10955:50;;;11001:1;10998;10991:12;10955:50;11038:4;11030:6;11026:17;11014:29;;11098:3;11091:4;11081:6;11078:1;11074:14;11066:6;11062:27;11058:38;11055:47;11052:67;;;11115:1;11112;11105:12;11130:1338;11290:6;11298;11306;11314;11322;11330;11338;11346;11399:3;11387:9;11378:7;11374:23;11370:33;11367:53;;;11416:1;11413;11406:12;11367:53;11455:9;11442:23;11474:31;11499:5;11474:31;:::i;:::-;11524:5;-1:-1:-1;11581:2:137;11566:18;;11553:32;11594:33;11553:32;11594:33;:::i;:::-;11646:7;-1:-1:-1;11704:2:137;11689:18;;11676:32;-1:-1:-1;;;;;11757:14:137;;;11754:34;;;11784:1;11781;11774:12;11754:34;11823:70;11885:7;11876:6;11865:9;11861:22;11823:70;:::i;:::-;11912:8;;-1:-1:-1;11797:96:137;-1:-1:-1;12000:2:137;11985:18;;11972:32;;-1:-1:-1;12016:16:137;;;12013:36;;;12045:1;12042;12035:12;12013:36;12084:72;12148:7;12137:8;12126:9;12122:24;12084:72;:::i;:::-;12175:8;;-1:-1:-1;12058:98:137;-1:-1:-1;12263:3:137;12248:19;;12235:33;;-1:-1:-1;12280:16:137;;;12277:36;;;12309:1;12306;12299:12;12277:36;;12348:60;12400:7;12389:8;12378:9;12374:24;12348:60;:::i;:::-;11130:1338;;;;-1:-1:-1;11130:1338:137;;-1:-1:-1;11130:1338:137;;;;;;12427:8;-1:-1:-1;;;11130:1338:137:o;12672:245::-;12762:6;12815:2;12803:9;12794:7;12790:23;12786:32;12783:52;;;12831:1;12828;12821:12;12783:52;12854:57;12903:7;12892:9;12854:57;:::i;12922:823::-;13028:6;13036;13044;13052;13060;13068;13121:3;13109:9;13100:7;13096:23;13092:33;13089:53;;;13138:1;13135;13128:12;13089:53;13177:9;13164:23;13196:31;13221:5;13196:31;:::i;:::-;13246:5;-1:-1:-1;13303:2:137;13288:18;;13275:32;13316:33;13275:32;13316:33;:::i;:::-;13368:7;-1:-1:-1;13422:2:137;13407:18;;13394:32;;-1:-1:-1;13473:2:137;13458:18;;13445:32;;-1:-1:-1;13528:3:137;13513:19;;13500:33;-1:-1:-1;;;;;13545:30:137;;13542:50;;;13588:1;13585;13578:12;13542:50;13627:58;13677:7;13668:6;13657:9;13653:22;13627:58;:::i;:::-;12922:823;;;;-1:-1:-1;12922:823:137;;-1:-1:-1;12922:823:137;;13704:8;;12922:823;-1:-1:-1;;;12922:823:137:o;13750:138::-;13829:13;;13851:31;13829:13;13851:31;:::i;13893:251::-;13963:6;14016:2;14004:9;13995:7;13991:23;13987:32;13984:52;;;14032:1;14029;14022:12;13984:52;14064:9;14058:16;14083:31;14108:5;14083:31;:::i;14357:897::-;14437:6;14490:2;14478:9;14469:7;14465:23;14461:32;14458:52;;;14506:1;14503;14496:12;14458:52;14539:9;14533:16;-1:-1:-1;;;;;14609:2:137;14601:6;14598:14;14595:34;;;14625:1;14622;14615:12;14595:34;14663:6;14652:9;14648:22;14638:32;;14708:7;14701:4;14697:2;14693:13;14689:27;14679:55;;14730:1;14727;14720:12;14679:55;14759:2;14753:9;14781:2;14777;14774:10;14771:36;;;14787:18;;:::i;:::-;14862:2;14856:9;14830:2;14916:13;;-1:-1:-1;;14912:22:137;;;14936:2;14908:31;14904:40;14892:53;;;14960:18;;;14980:22;;;14957:46;14954:72;;;15006:18;;:::i;:::-;15046:10;15042:2;15035:22;15081:2;15073:6;15066:18;15121:7;15116:2;15111;15107;15103:11;15099:20;15096:33;15093:53;;;15142:1;15139;15132:12;15093:53;15155:68;15220:2;15215;15207:6;15203:15;15198:2;15194;15190:11;15155:68;:::i;15259:247::-;15318:6;15371:2;15359:9;15350:7;15346:23;15342:32;15339:52;;;15387:1;15384;15377:12;15339:52;15426:9;15413:23;15445:31;15470:5;15445:31;:::i;15790:165::-;15857:20;;15917:12;15906:24;;15896:35;;15886:63;;15945:1;15942;15935:12;15960:184;16018:6;16071:2;16059:9;16050:7;16046:23;16042:32;16039:52;;;16087:1;16084;16077:12;16039:52;16110:28;16128:9;16110:28;:::i;16770:118::-;16856:5;16849:13;16842:21;16835:5;16832:32;16822:60;;16878:1;16875;16868:12;16893:245;16960:6;17013:2;17001:9;16992:7;16988:23;16984:32;16981:52;;;17029:1;17026;17019:12;16981:52;17061:9;17055:16;17080:28;17102:5;17080:28;:::i;17723:127::-;17784:10;17779:3;17775:20;17772:1;17765:31;17815:4;17812:1;17805:15;17839:4;17836:1;17829:15;17855:174;17922:12;17954:10;;;17966;;;17950:27;;17989:11;;;17986:37;;;18003:18;;:::i;:::-;17986:37;17855:174;;;;:::o;18332:125::-;18397:9;;;18418:10;;;18415:36;;;18431:18;;:::i;18462:1034::-;18701:20;;18683:39;;18670:3;18655:19;;18769:4;18757:17;;18744:31;18784;18744;18784;:::i;:::-;-1:-1:-1;;;;;18853:31:137;18846:4;18831:20;;18824:61;18948:4;18936:17;;;18923:31;18901:20;;;18894:61;18984:36;19014:4;19002:17;;18984:36;:::i;:::-;19039:12;19107:2;19093:12;19089:21;19082:4;19071:9;19067:20;19060:51;19191:2;19153:36;19183:4;19175:6;19171:17;19153:36;:::i;:::-;19149:45;19142:4;19131:9;19127:20;19120:75;;;19244:4;19236:6;19232:17;19219:31;19259:33;19284:7;19259:33;:::i;:::-;-1:-1:-1;;;;;4770:31:137;;19344:4;19329:20;;4758:44;19301:49;19413:4;19405:6;19401:17;19388:31;19381:4;19370:9;19366:20;19359:61;19483:4;19475:6;19471:17;19458:31;19451:4;19440:9;19436:20;19429:61;18462:1034;;;;:::o;19851:359::-;20038:6;20033:3;20026:19;20008:3;20074:6;20068:13;20090:73;20156:6;20151:2;20146:3;20142:12;20137:2;20129:6;20125:15;20090:73;:::i;:::-;20183:16;;;;20201:2;20179:25;;19851:359;-1:-1:-1;;;19851:359:137:o;20612:241::-;20668:6;20721:2;20709:9;20700:7;20696:23;20692:32;20689:52;;;20737:1;20734;20727:12;20689:52;20776:9;20763:23;20795:28;20817:5;20795:28;:::i;21137:521::-;21214:4;21220:6;21280:11;21267:25;21374:2;21370:7;21359:8;21343:14;21339:29;21335:43;21315:18;21311:68;21301:96;;21393:1;21390;21383:12;21301:96;21420:33;;21472:20;;;-1:-1:-1;;;;;;21504:30:137;;21501:50;;;21547:1;21544;21537:12;21501:50;21580:4;21568:17;;-1:-1:-1;21611:14:137;21607:27;;;21597:38;;21594:58;;;21648:1;21645;21638:12;21663:545;21756:4;21762:6;21822:11;21809:25;21916:2;21912:7;21901:8;21885:14;21881:29;21877:43;21857:18;21853:68;21843:96;;21935:1;21932;21925:12;21843:96;21962:33;;22014:20;;;-1:-1:-1;;;;;;22046:30:137;;22043:50;;;22089:1;22086;22079:12;22043:50;22122:4;22110:17;;-1:-1:-1;22173:1:137;22169:14;;;22153;22149:35;22139:46;;22136:66;;;22198:1;22195;22188:12;22213:266;22301:6;22296:3;22289:19;22353:6;22346:5;22339:4;22334:3;22330:14;22317:43;-1:-1:-1;22405:1:137;22380:16;;;22398:4;22376:27;;;22369:38;;;;22461:2;22440:15;;;-1:-1:-1;;22436:29:137;22427:39;;;22423:50;;22213:266::o;22484:979::-;22870:1;22866;22861:3;22857:11;22853:19;22845:6;22841:32;22830:9;22823:51;22910:6;22905:2;22894:9;22890:18;22883:34;22953:3;22948:2;22937:9;22933:18;22926:31;22804:4;22980:62;23037:3;23026:9;23022:19;23014:6;23006;22980:62;:::i;:::-;23078:22;;;23073:2;23058:18;;23051:50;23110:22;;;-1:-1:-1;;;;;23144:31:137;;23141:51;;;23188:1;23185;23178:12;23141:51;23222:6;23219:1;23215:14;23276:6;23268;23263:2;23255:6;23251:15;23238:45;23302:19;23362:18;;;23382:2;23358:27;;;23352:3;23337:19;;23330:56;23403:54;;23445:11;;23437:6;23429;23403:54;:::i;:::-;23395:62;22484:979;-1:-1:-1;;;;;;;;;;;22484:979:137:o;23468:167::-;23546:13;;23599:10;23588:22;;23578:33;;23568:61;;23625:1;23622;23615:12;23640:737;23703:5;23751:4;23739:9;23734:3;23730:19;23726:30;23723:50;;;23769:1;23766;23759:12;23723:50;23802:2;23796:9;23844:4;23836:6;23832:17;23915:6;23903:10;23900:22;-1:-1:-1;;;;;23867:10:137;23864:34;23861:62;23858:88;;;23926:18;;:::i;:::-;23966:10;23962:2;23955:22;;23995:6;23986:15;;24031:9;24025:16;24050:39;24081:7;24050:39;:::i;:::-;24098:23;;24166:2;24151:18;;24145:25;24179:33;24145:25;24179:33;:::i;:::-;24245:7;24240:2;24232:6;24228:15;24221:32;;24307:2;24296:9;24292:18;24286:25;24281:2;24273:6;24269:15;24262:50;24366:2;24355:9;24351:18;24345:25;24340:2;24332:6;24328:15;24321:50;;23640:737;;;;:::o;24382:165::-;24460:13;;24513:8;24502:20;;24492:31;;24482:59;;24537:1;24534;24527:12;24552:1104;24655:6;24663;24707:9;24698:7;24694:23;24737:3;24733:2;24729:12;24726:32;;;24754:1;24751;24744:12;24726:32;24783:9;24777:16;24767:26;;24812:6;24852:2;24846;24842:7;24838:2;24834:16;24830:25;24827:45;;;24868:1;24865;24858:12;24827:45;24894:17;;:::i;:::-;24881:30;;24934:49;24979:2;24968:9;24964:18;24934:49;:::i;:::-;24927:5;24920:64;25016:49;25061:2;25050:9;25046:18;25016:49;:::i;:::-;25011:2;25004:5;25000:14;24993:73;25098:48;25142:2;25131:9;25127:18;25098:48;:::i;:::-;25093:2;25086:5;25082:14;25075:72;25179:64;25235:7;25229:3;25218:9;25214:19;25179:64;:::i;:::-;25174:2;25167:5;25163:14;25156:88;25263:3;25299:63;25354:7;25349:2;25338:9;25334:18;25299:63;:::i;:::-;25293:3;25286:5;25282:15;25275:88;25418:3;25407:9;25403:19;25397:26;25390:4;25383:5;25379:16;25372:52;25458:49;25502:3;25491:9;25487:19;25458:49;:::i;:::-;25451:4;25440:16;;25433:75;25562:3;25547:19;;25541:26;25535:3;25524:15;;25517:51;25606:18;;25600:25;25584:14;;;25577:49;;;;-1:-1:-1;24552:1104:137;25444:5;;-1:-1:-1;24552:1104:137:o;26497:210::-;26598:5;26585:19;26613:33;26638:7;26613:33;:::i;:::-;-1:-1:-1;;;;;26667:33:137;26655:46;;;-1:-1:-1;26497:210:137:o;26712:1434::-;27065:25;;;27118:13;;-1:-1:-1;;;;;4770:31:137;27148:2;27133:18;;4758:44;27024:4;27053:3;27199:2;27187:15;;27181:22;-1:-1:-1;;;;;4770:31:137;;27260:2;27245:18;;4758:44;-1:-1:-1;27313:2:137;27301:15;;27295:22;9917:10;9906:22;;27375:2;27360:18;;9894:35;27326:53;27428:2;27420:6;27416:15;27410:22;27441:60;27496:3;27485:9;27481:19;27465:14;27441:60;:::i;:::-;;27550:3;27542:6;27538:16;27532:23;27574:3;27586:59;27641:2;27630:9;27626:18;27610:14;27586:59;:::i;:::-;27700:4;27688:17;;27682:24;27676:3;27661:19;;27654:53;27756:4;27744:17;;27738:24;4889:8;4878:20;27820:3;27805:19;;4866:33;27880:4;27868:17;;27862:24;27856:3;27841:19;;27834:53;27930:15;;27924:22;27918:3;27903:19;;27896:51;-1:-1:-1;27956:66:137;28017:3;28002:19;;27994:6;27956:66;:::i;:::-;28059:2;28053:3;28042:9;28038:19;28031:31;28079:61;28136:2;28125:9;28121:18;28113:6;28105;28079:61;:::i;:::-;28071:69;26712:1434;-1:-1:-1;;;;;;;;26712:1434:137:o;28429:168::-;28469:7;28535:1;28531;28527:6;28523:14;28520:1;28517:21;28512:1;28505:9;28498:17;28494:45;28491:71;;;28542:18;;:::i;:::-;-1:-1:-1;28582:9:137;;28429:168::o;28602:344::-;28796:2;28781:18;;28821:20;;28850:31;28821:20;28850:31;:::i;:::-;-1:-1:-1;;;;;28908:31:137;28890:50;;;28602:344;;-1:-1:-1;28602:344:137:o;29744:289::-;29919:6;29908:9;29901:25;29962:2;29957;29946:9;29942:18;29935:30;29882:4;29982:45;30023:2;30012:9;30008:18;30000:6;29982:45;:::i;30038:287::-;30167:3;30205:6;30199:13;30221:66;30280:6;30275:3;30268:4;30260:6;30256:17;30221:66;:::i;:::-;30303:16;;;;;30038:287;-1:-1:-1;;30038:287:137:o;30330:184::-;30400:6;30453:2;30441:9;30432:7;30428:23;30424:32;30421:52;;;30469:1;30466;30459:12;30421:52;-1:-1:-1;30492:16:137;;30330:184;-1:-1:-1;30330:184:137:o;30948:237::-;31124:3;31109:19;;31137:42;31113:9;31161:6;31137:42;:::i;31190:128::-;31257:9;;;31278:11;;;31275:37;;;31292:18;;:::i;31323:127::-;31384:10;31379:3;31375:20;31372:1;31365:31;31415:4;31412:1;31405:15;31439:4;31436:1;31429:15;31455:217;31495:1;31521;31511:132;;31565:10;31560:3;31556:20;31553:1;31546:31;31600:4;31597:1;31590:15;31628:4;31625:1;31618:15;31511:132;-1:-1:-1;31657:9:137;;31455:217::o;31866:276::-;31935:6;31988:2;31976:9;31967:7;31963:23;31959:32;31956:52;;;32004:1;32001;31994:12;31956:52;32036:9;32030:16;32086:6;32079:5;32075:18;32068:5;32065:29;32055:57;;32108:1;32105;32098:12;33319:273;33387:6;33440:2;33428:9;33419:7;33415:23;33411:32;33408:52;;;33456:1;33453;33446:12;33408:52;33488:9;33482:16;33538:4;33531:5;33527:16;33520:5;33517:27;33507:55;;33558:1;33555;33548:12","linkReferences":{},"immutableReferences":{"63127":[{"start":778,"length":32},{"start":5101,"length":32}],"63130":[{"start":817,"length":32},{"start":5322,"length":32}],"63133":[{"start":557,"length":32},{"start":1534,"length":32},{"start":2713,"length":32},{"start":4235,"length":32},{"start":4829,"length":32},{"start":9364,"length":32},{"start":10350,"length":32},{"start":11349,"length":32}],"63136":[{"start":1107,"length":32},{"start":1865,"length":32},{"start":6772,"length":32},{"start":9974,"length":32},{"start":10153,"length":32},{"start":10488,"length":32},{"start":10924,"length":32},{"start":13278,"length":32}],"63139":[{"start":1205,"length":32},{"start":2434,"length":32},{"start":3266,"length":32},{"start":5658,"length":32}],"63142":[{"start":957,"length":32},{"start":5061,"length":32}]}},"methodIdentifiers":{"ACCRUING_INTEREST_APR_DECIMALS()":"9e8f9540","ACCRUING_INTEREST_APR_DENOMINATOR()":"97b090ea","DOMAIN_SEPARATOR()":"3644e515","EXTENSION_PROPOSAL_TYPEHASH()":"4acacdda","MAX_ACCRUING_INTEREST_APR()":"c399e17d","MAX_EXTENSION_DURATION()":"2c8ebec8","MINUTES_IN_YEAR()":"0eb6f582","MIN_EXTENSION_DURATION()":"7f24133f","MIN_LOAN_DURATION()":"89d99a05","VERSION()":"ffa1ad74","categoryRegistry()":"58099d96","claimLOAN(uint256)":"0ee1ba17","config()":"79502c55","createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)":"764d7713","extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)":"1742123c","extensionProposalsMade(bytes32)":"640d16ed","getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":"74baf6ef","getLOAN(uint256)":"3e6df512","getLenderSpecHash((address))":"c8198080","getStateFingerprint(uint256)":"f5112315","hub()":"365a86fc","isValidAsset((uint8,address,uint256,uint256))":"7122192c","loanMetadataUri()":"111d8a15","loanRepaymentAmount(uint256)":"2c3eae8a","loanToken()":"06d37817","makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":"376af4d1","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","repayLOAN(uint256)":"706048df","revokedNonce()":"9788ad55","supportsInterface(bytes4)":"01ffc9a7","tryClaimRepaidLOAN(uint256,uint256,address)":"94aedc2f"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_hub\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_loanToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_config\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_revokedNonce\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_categoryRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"AddressMissingHubTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotLOANTokenHolder\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotVault\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"Expired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncompleteTransfer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InterestAPROutOfBounds\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtensionCaller\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InvalidExtensionDuration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"allowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"InvalidExtensionSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"current\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"InvalidLenderSpecHash\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"InvalidMultiTokenAsset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"digest\",\"type\":\"bytes32\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"name\":\"InvalidSourceOfFunds\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"timestap\",\"type\":\"uint40\"}],\"name\":\"LoanDefaulted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanNotAutoclaimable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanNotRepaid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanNotRunning\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanRepaid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanRunning\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistingLoan\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceNotUsable\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"currentBorrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newBorrower\",\"type\":\"address\"}],\"name\":\"RefinanceBorrowerMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RefinanceCollateralMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RefinanceCreditMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"categoryValue\",\"type\":\"uint8\"}],\"name\":\"UnsupportedCategory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedTransferFunction\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"VaultTransferSameSourceAndDestination\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"extensionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"ExtensionProposalMade\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"defaulted\",\"type\":\"bool\"}],\"name\":\"LOANClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposalContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"lender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"duration\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"credit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"bytes32\",\"name\":\"lenderSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"borrowerSpecHash\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoan.Terms\",\"name\":\"terms\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoan.LenderSpec\",\"name\":\"lenderSpec\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extra\",\"type\":\"bytes\"}],\"name\":\"LOANCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"originalDefaultTimestamp\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"extendedDefaultTimestamp\",\"type\":\"uint40\"}],\"name\":\"LOANExtended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"LOANPaidBack\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAdapter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"PoolSupply\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAdapter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"PoolWithdraw\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"}],\"name\":\"VaultPull\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"VaultPush\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"VaultPushFrom\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ACCRUING_INTEREST_APR_DECIMALS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ACCRUING_INTEREST_APR_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"EXTENSION_PROPOSAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_ACCRUING_INTEREST_APR\",\"outputs\":[{\"internalType\":\"uint40\",\"name\":\"\",\"type\":\"uint40\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_EXTENSION_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINUTES_IN_YEAR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_EXTENSION_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_LOAN_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"categoryRegistry\",\"outputs\":[{\"internalType\":\"contract IMultiTokenCategoryRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"claimLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"internalType\":\"contract PWNConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"proposalContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"proposalData\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"proposalInclusionProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PWNSimpleLoan.ProposalSpec\",\"name\":\"proposalSpec\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoan.LenderSpec\",\"name\":\"lenderSpec\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"revokeNonce\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.CallerSpec\",\"name\":\"callerSpec\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"extra\",\"type\":\"bytes\"}],\"name\":\"createLOAN\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"extension\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"extendLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"extensionProposalsMade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"extension\",\"type\":\"tuple\"}],\"name\":\"getExtensionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"getLOAN\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint40\",\"name\":\"startTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"defaultTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"originalLender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"loanOwner\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"credit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"originalSourceOfFunds\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repaymentAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoan.LenderSpec\",\"name\":\"lenderSpec\",\"type\":\"tuple\"}],\"name\":\"getLenderSpecHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getStateFingerprint\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hub\",\"outputs\":[{\"internalType\":\"contract PWNHub\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"}],\"name\":\"isValidAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loanMetadataUri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"loanRepaymentAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loanToken\",\"outputs\":[{\"internalType\":\"contract PWNLOAN\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"extension\",\"type\":\"tuple\"}],\"name\":\"makeExtensionProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"repayLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"revokedNonce\",\"outputs\":[{\"internalType\":\"contract PWNRevokedNonce\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanOwner\",\"type\":\"address\"}],\"name\":\"tryClaimRepaidLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Acts as a vault for every loan created by this contract.\",\"errors\":{\"InvalidMultiTokenAsset(uint8,address,uint256,uint256)\":[{\"details\":\"Could be because of invalid category, address, id or amount.\"}],\"InvalidSignature(address,bytes32)\":[{\"details\":\"Thrown when signature is invalid.\"}],\"InvalidSignatureLength(uint256)\":[{\"details\":\"Thrown when signature length is not 64 nor 65 bytes.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"details\":\"Maybe nonce is revoked or not in the current nonce space.\"}],\"UnsupportedCategory(uint8)\":[{\"params\":{\"categoryValue\":\"Value of the unsupported category.\"}}]},\"kind\":\"dev\",\"methods\":{\"claimLOAN(uint256)\":{\"details\":\"Only a LOAN token holder can claim a repaid or defaulted loan. Claim will transfer the repaid credit or collateral to a LOAN token holder address and burn the LOAN token.\",\"params\":{\"loanId\":\"Id of a loan that is being claimed.\"}},\"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)\":{\"details\":\"The function assumes a prior token approval to a contract address.\",\"params\":{\"callerSpec\":\"Caller specification struct.\",\"extra\":\"Auxiliary data that are emitted in the loan creation event. They are not used in the contract logic.\",\"lenderSpec\":\"Lender specification struct.\",\"proposalSpec\":\"Proposal specification struct.\"},\"returns\":{\"loanId\":\"Id of the created LOAN token.\"}},\"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)\":{\"details\":\"The function assumes a prior token approval to a contract address.\",\"params\":{\"extension\":\"Extension proposal struct.\",\"signature\":\"Signature of the extension proposal.\"}},\"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"params\":{\"extension\":\"Extension proposal struct.\"},\"returns\":{\"_0\":\"Hash of the extension struct.\"}},\"getLOAN(uint256)\":{\"params\":{\"loanId\":\"Id of a loan in question.\"},\"returns\":{\"accruingInterestAPR\":\"Accruing interest APR with 2 decimal places.\",\"borrower\":\"Address of a loan borrower.\",\"collateral\":\"Asset used as a loan collateral. For a definition see { MultiToken dependency lib }.\",\"credit\":\"Asset used as a loan credit. For a definition see { MultiToken dependency lib }.\",\"defaultTimestamp\":\"Unix timestamp (in seconds) of a loan default date.\",\"fixedInterestAmount\":\"Fixed interest amount in credit asset tokens.\",\"loanOwner\":\"Address of a LOAN token holder.\",\"originalLender\":\"Address of a loan original lender.\",\"originalSourceOfFunds\":\"Address of a source of funds for the loan. Original lender address, if the loan was funded directly, or a pool address from witch credit funds were withdrawn / borrowred.\",\"repaymentAmount\":\"Loan repayment amount in credit asset tokens.\",\"startTimestamp\":\"Unix timestamp (in seconds) of a loan creation date.\",\"status\":\"LOAN status.\"}},\"getLenderSpecHash((address))\":{\"params\":{\"lenderSpec\":\"Lender specification struct.\"},\"returns\":{\"_0\":\"Hash of a lender specification.\"}},\"getStateFingerprint(uint256)\":{\"params\":{\"tokenId\":\"Id of a token state in question.\"},\"returns\":{\"_0\":\"Current token state fingerprint.\"}},\"isValidAsset((uint8,address,uint256,uint256))\":{\"details\":\"See MultiToken.isValid for more details.\",\"params\":{\"asset\":\"Asset to be checked.\"},\"returns\":{\"_0\":\"True if the asset is valid.\"}},\"loanMetadataUri()\":{\"returns\":{\"_0\":\"LOAN token metadata uri.\"}},\"loanRepaymentAmount(uint256)\":{\"params\":{\"loanId\":\"Id of a loan.\"},\"returns\":{\"_0\":\"Repayment amount.\"}},\"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"params\":{\"extension\":\"Extension proposal struct.\"}},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` (i.e. 0xbc197c81, or its own function selector).\",\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\"}},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` (i.e. 0xf23a6e61, or its own function selector).\",\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\"}},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\",\"returns\":{\"_0\":\"`IERC721Receiver.onERC721Received.selector` if transfer is allowed\"}},\"repayLOAN(uint256)\":{\"details\":\"Any address can repay a running loan, but a collateral will be transferred to a borrower address associated with the loan. If the LOAN token holder is the same as the original lender, the repayment credit asset will be transferred to the LOAN token holder directly. Otherwise it will transfer the repayment credit asset to a vault, waiting on a LOAN token holder to claim it. The function assumes a prior token approval to a contract address.\",\"params\":{\"loanId\":\"Id of a loan that is being repaid.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"tryClaimRepaidLOAN(uint256,uint256,address)\":{\"details\":\"The function is called by the vault to repay a loan directly to the original lender or its source of funds if the loan owner is the original lender. If the transfer fails, the LOAN token will remain in repaid state and the LOAN token owner will be able to claim the repaid credit. Otherwise lender would be able to prevent borrower from repaying the loan.\",\"params\":{\"creditAmount\":\"Amount of a credit to be claimed.\",\"loanId\":\"Id of a loan that is being claimed.\",\"loanOwner\":\"Address of the LOAN token holder.\"}}},\"title\":\"PWN Simple Loan\",\"version\":1},\"userdoc\":{\"errors\":{\"AddressMissingHubTag(address,bytes32)\":[{\"notice\":\"Thrown when an address is missing a PWN Hub tag.\"}],\"CallerNotLOANTokenHolder()\":[{\"notice\":\"Thrown when caller is not a LOAN token holder.\"}],\"CallerNotVault()\":[{\"notice\":\"Thrown when caller is not a vault.\"}],\"Expired(uint256,uint256)\":[{\"notice\":\"Thrown when a proposal is expired.\"}],\"IncompleteTransfer()\":[{\"notice\":\"Thrown when an asset transfer is incomplete.\"}],\"InterestAPROutOfBounds(uint256,uint256)\":[{\"notice\":\"Thrown when accruing interest APR is above the maximum.\"}],\"InvalidDuration(uint256,uint256)\":[{\"notice\":\"Thrown when loan duration is below the minimum.\"}],\"InvalidExtensionCaller()\":[{\"notice\":\"Thrown when caller is not a loan borrower or lender.\"}],\"InvalidExtensionDuration(uint256,uint256)\":[{\"notice\":\"Thrown when loan extension duration is out of bounds.\"}],\"InvalidExtensionSigner(address,address)\":[{\"notice\":\"Thrown when signer is not a loan extension proposer.\"}],\"InvalidLenderSpecHash(bytes32,bytes32)\":[{\"notice\":\"Thrown when hash of provided lender spec doesn't match the one in loan terms.\"}],\"InvalidMultiTokenAsset(uint8,address,uint256,uint256)\":[{\"notice\":\"Thrown when MultiToken.Asset is invalid.\"}],\"InvalidSourceOfFunds(address)\":[{\"notice\":\"Thrown when pool based source of funds doesn't have a registered adapter.\"}],\"LoanDefaulted(uint40)\":[{\"notice\":\"Thrown when managed loan is defaulted.\"}],\"LoanNotAutoclaimable()\":[{\"notice\":\"Thrown when loan cannot be claimed on repayment.\"}],\"LoanNotRepaid()\":[{\"notice\":\"Thrown when managed loan is not repaid.\"}],\"LoanNotRunning()\":[{\"notice\":\"Thrown when managed loan is running.\"}],\"LoanRepaid()\":[{\"notice\":\"Thrown when managed loan is repaid.\"}],\"LoanRunning()\":[{\"notice\":\"Thrown when manged loan is still running.\"}],\"NonExistingLoan()\":[{\"notice\":\"Thrown when loan doesn't exist.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"notice\":\"Thrown when nonce is currently not usable.\"}],\"RefinanceBorrowerMismatch(address,address)\":[{\"notice\":\"Thrown when refinancing loan terms have different borrower than the original loan.\"}],\"RefinanceCollateralMismatch()\":[{\"notice\":\"Thrown when refinancing loan terms have different collateral asset than the original loan.\"}],\"RefinanceCreditMismatch()\":[{\"notice\":\"Thrown when refinancing loan terms have different credit asset than the original loan.\"}],\"UnsupportedCategory(uint8)\":[{\"notice\":\"Thrown when unsupported category is used.\"}],\"UnsupportedTransferFunction()\":[{\"notice\":\"Thrown when the Vault receives an asset that is not transferred by the Vault itself.\"}],\"VaultTransferSameSourceAndDestination(address)\":[{\"notice\":\"Thrown when an asset transfer source and destination address are the same.\"}]},\"events\":{\"ExtensionProposalMade(bytes32,address,(uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"notice\":\"Emitted when a loan extension proposal is made.\"},\"LOANClaimed(uint256,bool)\":{\"notice\":\"Emitted when a repaid or defaulted loan is claimed.\"},\"LOANCreated(uint256,bytes32,address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes)\":{\"notice\":\"Emitted when a new loan in created.\"},\"LOANExtended(uint256,uint40,uint40)\":{\"notice\":\"Emitted when a LOAN token holder extends a loan.\"},\"LOANPaidBack(uint256)\":{\"notice\":\"Emitted when a loan is paid back.\"},\"PoolSupply((uint8,address,uint256,uint256),address,address,address)\":{\"notice\":\"Emitted when asset is supplied to a pool from a vault.\"},\"PoolWithdraw((uint8,address,uint256,uint256),address,address,address)\":{\"notice\":\"Emitted when asset is withdrawn from a pool to an `owner` address.\"},\"VaultPull((uint8,address,uint256,uint256),address)\":{\"notice\":\"Emitted when asset transfer happens from an `origin` address to a vault.\"},\"VaultPush((uint8,address,uint256,uint256),address)\":{\"notice\":\"Emitted when asset transfer happens from a vault to a `beneficiary` address.\"},\"VaultPushFrom((uint8,address,uint256,uint256),address,address)\":{\"notice\":\"Emitted when asset transfer happens from an `origin` address to a `beneficiary` address.\"}},\"kind\":\"user\",\"methods\":{\"claimLOAN(uint256)\":{\"notice\":\"Claim a repaid or defaulted loan.\"},\"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)\":{\"notice\":\"Create a new loan.\"},\"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)\":{\"notice\":\"Extend loans default date with signed extension proposal signed by borrower or LOAN token owner.\"},\"extensionProposalsMade(bytes32)\":{\"notice\":\"Mapping of extension proposals made via on-chain transaction by extension hash.\"},\"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"notice\":\"Get the hash of the extension struct.\"},\"getLOAN(uint256)\":{\"notice\":\"Return a LOAN data struct associated with a loan id.\"},\"getLenderSpecHash((address))\":{\"notice\":\"Get hash of a lender specification.\"},\"getStateFingerprint(uint256)\":{\"notice\":\"Function to return current token state fingerprint.\"},\"isValidAsset((uint8,address,uint256,uint256))\":{\"notice\":\"Check if the asset is valid with the MultiToken dependency lib and the category registry.\"},\"loanMetadataUri()\":{\"notice\":\"Get a loan metadata uri for a LOAN token minted by this contract.\"},\"loanRepaymentAmount(uint256)\":{\"notice\":\"Calculate the loan repayment amount with fixed and accrued interest.\"},\"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"notice\":\"Make an on-chain extension proposal.\"},\"repayLOAN(uint256)\":{\"notice\":\"Repay running loan.\"},\"tryClaimRepaidLOAN(uint256,uint256,address)\":{\"notice\":\"Try to claim a repaid loan for the loan owner.\"}},\"notice\":\"Contract managing a simple loan in PWN protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/loan/terms/simple/loan/PWNSimpleLoan.sol\":\"PWNSimpleLoan\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/MultiToken/src/MultiToken.sol\":{\"keccak256\":\"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18\",\"dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh\"]},\"lib/MultiToken/src/interfaces/ICryptoKitties.sol\":{\"keccak256\":\"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa\",\"dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze\"]},\"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol\":{\"keccak256\":\"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1\",\"dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\":{\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16\",\"dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c\",\"dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e\",\"dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b\",\"dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95\",\"dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol\":{\"keccak256\":\"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b\",\"dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45\",\"dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol\":{\"keccak256\":\"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8\",\"dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6\"]},\"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol\":{\"keccak256\":\"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf\",\"dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec\",\"dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005\",\"dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4\",\"dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol\":{\"keccak256\":\"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04\",\"dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd\",\"dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278\",\"dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"src/PWNErrors.sol\":{\"keccak256\":\"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f\",\"dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc\"]},\"src/config/PWNConfig.sol\":{\"keccak256\":\"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7\",\"dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]},\"src/hub/PWNHubTags.sol\":{\"keccak256\":\"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8\",\"dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ\"]},\"src/interfaces/IERC5646.sol\":{\"keccak256\":\"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180\",\"dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki\"]},\"src/interfaces/IPWNLoanMetadataProvider.sol\":{\"keccak256\":\"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6\",\"dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK\"]},\"src/interfaces/IPoolAdapter.sol\":{\"keccak256\":\"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b\",\"dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T\"]},\"src/interfaces/IStateFingerpringComputer.sol\":{\"keccak256\":\"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c\",\"dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct\"]},\"src/loan/lib/PWNFeeCalculator.sol\":{\"keccak256\":\"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5\",\"dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq\"]},\"src/loan/lib/PWNSignatureChecker.sol\":{\"keccak256\":\"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1\",\"dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM\"]},\"src/loan/terms/simple/loan/PWNSimpleLoan.sol\":{\"keccak256\":\"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129\",\"dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP\"]},\"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol\":{\"keccak256\":\"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13\",\"dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP\"]},\"src/loan/token/PWNLOAN.sol\":{\"keccak256\":\"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219\",\"dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo\"]},\"src/loan/vault/PWNVault.sol\":{\"keccak256\":\"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b\",\"dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq\"]},\"src/nonce/PWNRevokedNonce.sol\":{\"keccak256\":\"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f\",\"dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS\"]},\"src/utilized-credit/PWNUtilizedCredit.sol\":{\"keccak256\":\"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441\",\"dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"address","name":"_loanToken","type":"address"},{"internalType":"address","name":"_config","type":"address"},{"internalType":"address","name":"_revokedNonce","type":"address"},{"internalType":"address","name":"_categoryRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"}],"type":"error","name":"AddressMissingHubTag"},{"inputs":[],"type":"error","name":"CallerNotLOANTokenHolder"},{"inputs":[],"type":"error","name":"CallerNotVault"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"type":"error","name":"Expired"},{"inputs":[],"type":"error","name":"IncompleteTransfer"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InterestAPROutOfBounds"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InvalidDuration"},{"inputs":[],"type":"error","name":"InvalidExtensionCaller"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InvalidExtensionDuration"},{"inputs":[{"internalType":"address","name":"allowed","type":"address"},{"internalType":"address","name":"current","type":"address"}],"type":"error","name":"InvalidExtensionSigner"},{"inputs":[{"internalType":"bytes32","name":"current","type":"bytes32"},{"internalType":"bytes32","name":"expected","type":"bytes32"}],"type":"error","name":"InvalidLenderSpecHash"},{"inputs":[{"internalType":"uint8","name":"category","type":"uint8"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"type":"error","name":"InvalidMultiTokenAsset"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"digest","type":"bytes32"}],"type":"error","name":"InvalidSignature"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"type":"error","name":"InvalidSignatureLength"},{"inputs":[{"internalType":"address","name":"sourceOfFunds","type":"address"}],"type":"error","name":"InvalidSourceOfFunds"},{"inputs":[{"internalType":"uint40","name":"timestap","type":"uint40"}],"type":"error","name":"LoanDefaulted"},{"inputs":[],"type":"error","name":"LoanNotAutoclaimable"},{"inputs":[],"type":"error","name":"LoanNotRepaid"},{"inputs":[],"type":"error","name":"LoanNotRunning"},{"inputs":[],"type":"error","name":"LoanRepaid"},{"inputs":[],"type":"error","name":"LoanRunning"},{"inputs":[],"type":"error","name":"NonExistingLoan"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"type":"error","name":"NonceNotUsable"},{"inputs":[{"internalType":"address","name":"currentBorrower","type":"address"},{"internalType":"address","name":"newBorrower","type":"address"}],"type":"error","name":"RefinanceBorrowerMismatch"},{"inputs":[],"type":"error","name":"RefinanceCollateralMismatch"},{"inputs":[],"type":"error","name":"RefinanceCreditMismatch"},{"inputs":[{"internalType":"uint8","name":"categoryValue","type":"uint8"}],"type":"error","name":"UnsupportedCategory"},{"inputs":[],"type":"error","name":"UnsupportedTransferFunction"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"type":"error","name":"VaultTransferSameSourceAndDestination"},{"inputs":[{"internalType":"bytes32","name":"extensionHash","type":"bytes32","indexed":true},{"internalType":"address","name":"proposer","type":"address","indexed":true},{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"proposal","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"indexed":false}],"type":"event","name":"ExtensionProposalMade","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"bool","name":"defaulted","type":"bool","indexed":true}],"type":"event","name":"LOANClaimed","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"bytes32","name":"proposalHash","type":"bytes32","indexed":true},{"internalType":"address","name":"proposalContract","type":"address","indexed":true},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256","indexed":false},{"internalType":"struct PWNSimpleLoan.Terms","name":"terms","type":"tuple","components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint32","name":"duration","type":"uint32"},{"internalType":"struct MultiToken.Asset","name":"collateral","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"struct MultiToken.Asset","name":"credit","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"bytes32","name":"lenderSpecHash","type":"bytes32"},{"internalType":"bytes32","name":"borrowerSpecHash","type":"bytes32"}],"indexed":false},{"internalType":"struct PWNSimpleLoan.LenderSpec","name":"lenderSpec","type":"tuple","components":[{"internalType":"address","name":"sourceOfFunds","type":"address"}],"indexed":false},{"internalType":"bytes","name":"extra","type":"bytes","indexed":false}],"type":"event","name":"LOANCreated","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"uint40","name":"originalDefaultTimestamp","type":"uint40","indexed":false},{"internalType":"uint40","name":"extendedDefaultTimestamp","type":"uint40","indexed":false}],"type":"event","name":"LOANExtended","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true}],"type":"event","name":"LOANPaidBack","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"poolAdapter","type":"address","indexed":true},{"internalType":"address","name":"pool","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true}],"type":"event","name":"PoolSupply","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"poolAdapter","type":"address","indexed":true},{"internalType":"address","name":"pool","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true}],"type":"event","name":"PoolWithdraw","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"origin","type":"address","indexed":true}],"type":"event","name":"VaultPull","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"beneficiary","type":"address","indexed":true}],"type":"event","name":"VaultPush","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"origin","type":"address","indexed":true},{"internalType":"address","name":"beneficiary","type":"address","indexed":true}],"type":"event","name":"VaultPushFrom","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"ACCRUING_INTEREST_APR_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"ACCRUING_INTEREST_APR_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"EXTENSION_PROPOSAL_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MAX_ACCRUING_INTEREST_APR","outputs":[{"internalType":"uint40","name":"","type":"uint40"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MAX_EXTENSION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MINUTES_IN_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MIN_EXTENSION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MIN_LOAN_DURATION","outputs":[{"internalType":"uint32","name":"","type":"uint32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"categoryRegistry","outputs":[{"internalType":"contract IMultiTokenCategoryRegistry","name":"","type":"address"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"claimLOAN"},{"inputs":[],"stateMutability":"view","type":"function","name":"config","outputs":[{"internalType":"contract PWNConfig","name":"","type":"address"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ProposalSpec","name":"proposalSpec","type":"tuple","components":[{"internalType":"address","name":"proposalContract","type":"address"},{"internalType":"bytes","name":"proposalData","type":"bytes"},{"internalType":"bytes32[]","name":"proposalInclusionProof","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]},{"internalType":"struct PWNSimpleLoan.LenderSpec","name":"lenderSpec","type":"tuple","components":[{"internalType":"address","name":"sourceOfFunds","type":"address"}]},{"internalType":"struct PWNSimpleLoan.CallerSpec","name":"callerSpec","type":"tuple","components":[{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"bool","name":"revokeNonce","type":"bool"},{"internalType":"uint256","name":"nonce","type":"uint256"}]},{"internalType":"bytes","name":"extra","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"createLOAN","outputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"extension","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}]},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"extendLOAN"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","name":"extensionProposalsMade","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"extension","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}]}],"stateMutability":"view","type":"function","name":"getExtensionHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getLOAN","outputs":[{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint40","name":"startTimestamp","type":"uint40"},{"internalType":"uint40","name":"defaultTimestamp","type":"uint40"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"originalLender","type":"address"},{"internalType":"address","name":"loanOwner","type":"address"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"struct MultiToken.Asset","name":"credit","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"struct MultiToken.Asset","name":"collateral","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"address","name":"originalSourceOfFunds","type":"address"},{"internalType":"uint256","name":"repaymentAmount","type":"uint256"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.LenderSpec","name":"lenderSpec","type":"tuple","components":[{"internalType":"address","name":"sourceOfFunds","type":"address"}]}],"stateMutability":"pure","type":"function","name":"getLenderSpecHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getStateFingerprint","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"hub","outputs":[{"internalType":"contract PWNHub","name":"","type":"address"}]},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]}],"stateMutability":"view","type":"function","name":"isValidAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"loanMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"view","type":"function","name":"loanRepaymentAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"loanToken","outputs":[{"internalType":"contract PWNLOAN","name":"","type":"address"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"extension","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}]}],"stateMutability":"nonpayable","type":"function","name":"makeExtensionProposal"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function","name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}]},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function","name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}]},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function","name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"repayLOAN"},{"inputs":[],"stateMutability":"view","type":"function","name":"revokedNonce","outputs":[{"internalType":"contract PWNRevokedNonce","name":"","type":"address"}]},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"pure","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"address","name":"loanOwner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"tryClaimRepaidLOAN"}],"devdoc":{"kind":"dev","methods":{"claimLOAN(uint256)":{"details":"Only a LOAN token holder can claim a repaid or defaulted loan. Claim will transfer the repaid credit or collateral to a LOAN token holder address and burn the LOAN token.","params":{"loanId":"Id of a loan that is being claimed."}},"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)":{"details":"The function assumes a prior token approval to a contract address.","params":{"callerSpec":"Caller specification struct.","extra":"Auxiliary data that are emitted in the loan creation event. They are not used in the contract logic.","lenderSpec":"Lender specification struct.","proposalSpec":"Proposal specification struct."},"returns":{"loanId":"Id of the created LOAN token."}},"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)":{"details":"The function assumes a prior token approval to a contract address.","params":{"extension":"Extension proposal struct.","signature":"Signature of the extension proposal."}},"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"params":{"extension":"Extension proposal struct."},"returns":{"_0":"Hash of the extension struct."}},"getLOAN(uint256)":{"params":{"loanId":"Id of a loan in question."},"returns":{"accruingInterestAPR":"Accruing interest APR with 2 decimal places.","borrower":"Address of a loan borrower.","collateral":"Asset used as a loan collateral. For a definition see { MultiToken dependency lib }.","credit":"Asset used as a loan credit. For a definition see { MultiToken dependency lib }.","defaultTimestamp":"Unix timestamp (in seconds) of a loan default date.","fixedInterestAmount":"Fixed interest amount in credit asset tokens.","loanOwner":"Address of a LOAN token holder.","originalLender":"Address of a loan original lender.","originalSourceOfFunds":"Address of a source of funds for the loan. Original lender address, if the loan was funded directly, or a pool address from witch credit funds were withdrawn / borrowred.","repaymentAmount":"Loan repayment amount in credit asset tokens.","startTimestamp":"Unix timestamp (in seconds) of a loan creation date.","status":"LOAN status."}},"getLenderSpecHash((address))":{"params":{"lenderSpec":"Lender specification struct."},"returns":{"_0":"Hash of a lender specification."}},"getStateFingerprint(uint256)":{"params":{"tokenId":"Id of a token state in question."},"returns":{"_0":"Current token state fingerprint."}},"isValidAsset((uint8,address,uint256,uint256))":{"details":"See MultiToken.isValid for more details.","params":{"asset":"Asset to be checked."},"returns":{"_0":"True if the asset is valid."}},"loanMetadataUri()":{"returns":{"_0":"LOAN token metadata uri."}},"loanRepaymentAmount(uint256)":{"params":{"loanId":"Id of a loan."},"returns":{"_0":"Repayment amount."}},"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"params":{"extension":"Extension proposal struct."}},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81, or its own function selector).","returns":{"_0":"`bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed"}},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61, or its own function selector).","returns":{"_0":"`bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed"}},"onERC721Received(address,address,uint256,bytes)":{"details":"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.","returns":{"_0":"`IERC721Receiver.onERC721Received.selector` if transfer is allowed"}},"repayLOAN(uint256)":{"details":"Any address can repay a running loan, but a collateral will be transferred to a borrower address associated with the loan. If the LOAN token holder is the same as the original lender, the repayment credit asset will be transferred to the LOAN token holder directly. Otherwise it will transfer the repayment credit asset to a vault, waiting on a LOAN token holder to claim it. The function assumes a prior token approval to a contract address.","params":{"loanId":"Id of a loan that is being repaid."}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"tryClaimRepaidLOAN(uint256,uint256,address)":{"details":"The function is called by the vault to repay a loan directly to the original lender or its source of funds if the loan owner is the original lender. If the transfer fails, the LOAN token will remain in repaid state and the LOAN token owner will be able to claim the repaid credit. Otherwise lender would be able to prevent borrower from repaying the loan.","params":{"creditAmount":"Amount of a credit to be claimed.","loanId":"Id of a loan that is being claimed.","loanOwner":"Address of the LOAN token holder."}}},"version":1},"userdoc":{"kind":"user","methods":{"claimLOAN(uint256)":{"notice":"Claim a repaid or defaulted loan."},"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)":{"notice":"Create a new loan."},"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)":{"notice":"Extend loans default date with signed extension proposal signed by borrower or LOAN token owner."},"extensionProposalsMade(bytes32)":{"notice":"Mapping of extension proposals made via on-chain transaction by extension hash."},"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"notice":"Get the hash of the extension struct."},"getLOAN(uint256)":{"notice":"Return a LOAN data struct associated with a loan id."},"getLenderSpecHash((address))":{"notice":"Get hash of a lender specification."},"getStateFingerprint(uint256)":{"notice":"Function to return current token state fingerprint."},"isValidAsset((uint8,address,uint256,uint256))":{"notice":"Check if the asset is valid with the MultiToken dependency lib and the category registry."},"loanMetadataUri()":{"notice":"Get a loan metadata uri for a LOAN token minted by this contract."},"loanRepaymentAmount(uint256)":{"notice":"Calculate the loan repayment amount with fixed and accrued interest."},"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"notice":"Make an on-chain extension proposal."},"repayLOAN(uint256)":{"notice":"Repay running loan."},"tryClaimRepaidLOAN(uint256,uint256,address)":{"notice":"Try to claim a repaid loan for the loan owner."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/loan/terms/simple/loan/PWNSimpleLoan.sol":"PWNSimpleLoan"},"evmVersion":"london","libraries":{}},"sources":{"lib/MultiToken/src/MultiToken.sol":{"keccak256":"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da","urls":["bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18","dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh"],"license":"MIT"},"lib/MultiToken/src/interfaces/ICryptoKitties.sol":{"keccak256":"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706","urls":["bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa","dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze"],"license":"MIT"},"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol":{"keccak256":"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a","urls":["bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1","dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol":{"keccak256":"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510","urls":["bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16","dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"keccak256":"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e","urls":["bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c","dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794","urls":["bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e","dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"keccak256":"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422","urls":["bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b","dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef","urls":["bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95","dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol":{"keccak256":"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2","urls":["bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b","dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45","urls":["bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45","dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol":{"keccak256":"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c","urls":["bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8","dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol":{"keccak256":"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582","urls":["bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf","dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol":{"keccak256":"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b","urls":["bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec","dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol":{"keccak256":"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac","urls":["bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04","dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol":{"keccak256":"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5","urls":["bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd","dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad","urls":["bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278","dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"src/PWNErrors.sol":{"keccak256":"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24","urls":["bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f","dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc"],"license":"GPL-3.0-only"},"src/config/PWNConfig.sol":{"keccak256":"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f","urls":["bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7","dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz"],"license":"GPL-3.0-only"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"},"src/hub/PWNHubTags.sol":{"keccak256":"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a","urls":["bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8","dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ"],"license":"GPL-3.0-only"},"src/interfaces/IERC5646.sol":{"keccak256":"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e","urls":["bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180","dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki"],"license":"GPL-3.0-only"},"src/interfaces/IPWNLoanMetadataProvider.sol":{"keccak256":"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8","urls":["bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6","dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK"],"license":"GPL-3.0-only"},"src/interfaces/IPoolAdapter.sol":{"keccak256":"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89","urls":["bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b","dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T"],"license":"GPL-3.0-only"},"src/interfaces/IStateFingerpringComputer.sol":{"keccak256":"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2","urls":["bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c","dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct"],"license":"GPL-3.0-only"},"src/loan/lib/PWNFeeCalculator.sol":{"keccak256":"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf","urls":["bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5","dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq"],"license":"GPL-3.0-only"},"src/loan/lib/PWNSignatureChecker.sol":{"keccak256":"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd","urls":["bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1","dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM"],"license":"GPL-3.0-only"},"src/loan/terms/simple/loan/PWNSimpleLoan.sol":{"keccak256":"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80","urls":["bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129","dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP"],"license":"GPL-3.0-only"},"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol":{"keccak256":"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96","urls":["bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13","dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP"],"license":"GPL-3.0-only"},"src/loan/token/PWNLOAN.sol":{"keccak256":"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb","urls":["bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219","dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo"],"license":"GPL-3.0-only"},"src/loan/vault/PWNVault.sol":{"keccak256":"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c","urls":["bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b","dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq"],"license":"GPL-3.0-only"},"src/nonce/PWNRevokedNonce.sol":{"keccak256":"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e","urls":["bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f","dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS"],"license":"GPL-3.0-only"},"src/utilized-credit/PWNUtilizedCredit.sol":{"keccak256":"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3","urls":["bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441","dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC"],"license":"GPL-3.0-only"}},"version":1},"id":93} \ No newline at end of file diff --git a/packages/subgraph/abis/SimpleLoanSimpleProposal.json b/packages/subgraph/abis/SimpleLoanSimpleProposal.json new file mode 100644 index 00000000..0063e9bc --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanSimpleProposal.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"_hub","type":"address","internalType":"address"},{"name":"_revokedNonce","type":"address","internalType":"address"},{"name":"_config","type":"address","internalType":"address"},{"name":"_utilizedCredit","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MULTIPROPOSAL_DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MULTIPROPOSAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"PROPOSAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"VERSION","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"acceptProposal","inputs":[{"name":"acceptor","type":"address","internalType":"address"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"proposalData","type":"bytes","internalType":"bytes"},{"name":"proposalInclusionProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"proposalHash","type":"bytes32","internalType":"bytes32"},{"name":"loanTerms","type":"tuple","internalType":"struct PWNSimpleLoan.Terms","components":[{"name":"lender","type":"address","internalType":"address"},{"name":"borrower","type":"address","internalType":"address"},{"name":"duration","type":"uint32","internalType":"uint32"},{"name":"collateral","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"credit","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"lenderSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"borrowerSpecHash","type":"bytes32","internalType":"bytes32"}]}],"stateMutability":"nonpayable"},{"type":"function","name":"config","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNConfig"}],"stateMutability":"view"},{"type":"function","name":"decodeProposalData","inputs":[{"name":"proposalData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"stateMutability":"pure"},{"type":"function","name":"encodeProposalData","inputs":[{"name":"proposal","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"pure"},{"type":"function","name":"getMultiproposalHash","inputs":[{"name":"multiproposal","type":"tuple","internalType":"struct PWNSimpleLoanProposal.Multiproposal","components":[{"name":"multiproposalMerkleRoot","type":"bytes32","internalType":"bytes32"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getProposalHash","inputs":[{"name":"proposal","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"hub","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNHub"}],"stateMutability":"view"},{"type":"function","name":"makeProposal","inputs":[{"name":"proposal","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"outputs":[{"name":"proposalHash","type":"bytes32","internalType":"bytes32"}],"stateMutability":"nonpayable"},{"type":"function","name":"proposalsMade","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"revokeNonce","inputs":[{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokedNonce","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNRevokedNonce"}],"stateMutability":"view"},{"type":"function","name":"utilizedCredit","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNUtilizedCredit"}],"stateMutability":"view"},{"type":"event","name":"ProposalMade","inputs":[{"name":"proposalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"proposer","type":"address","indexed":true,"internalType":"address"},{"name":"proposal","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"anonymous":false},{"type":"error","name":"AcceptorIsProposer","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"type":"error","name":"AddressMissingHubTag","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"CallerIsNotStatedProposer","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"type":"error","name":"CallerNotAllowedAcceptor","inputs":[{"name":"current","type":"address","internalType":"address"},{"name":"allowed","type":"address","internalType":"address"}]},{"type":"error","name":"CallerNotLoanContract","inputs":[{"name":"caller","type":"address","internalType":"address"},{"name":"loanContract","type":"address","internalType":"address"}]},{"type":"error","name":"DefaultDateInPast","inputs":[{"name":"defaultDate","type":"uint32","internalType":"uint32"},{"name":"current","type":"uint32","internalType":"uint32"}]},{"type":"error","name":"Expired","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"expiration","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidCollateralStateFingerprint","inputs":[{"name":"current","type":"bytes32","internalType":"bytes32"},{"name":"proposed","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidRefinancingLoanId","inputs":[{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSignature","inputs":[{"name":"signer","type":"address","internalType":"address"},{"name":"digest","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidSignatureLength","inputs":[{"name":"length","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"MissingStateFingerprintComputer","inputs":[]},{"type":"error","name":"NonceNotUsable","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"bytecode":{"object":"0x6101406040523480156200001257600080fd5b50604051620027a4380380620027a48339810160408190526200003591620001f6565b604080518082018252601b81527f50574e53696d706c654c6f616e53696d706c6550726f706f73616c0000000000602080830191909152825180840184526003815262312e3360e81b818301526001600160a01b0380891660c05280881660e05280871661010052851661012052925187938793879387939192917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f91620000e09185910162000253565b604051602081830303815290604052805190602001208260405160200162000109919062000253565b60408051601f1981840301815282825280516020918201209083019490945281019190915260608101919091524660808201523060a082015260c00160408051808303601f1901815282825280516020918201206080527fb2178a58fb1eefb359ecfdd57bb19c0bdd0f4e6eed8547f46600e500ed111af3908301527fb63b40822cc79278afd8d1ce1a8006a4a298ec829d4d1610b69b2a4830c232709082015260600160408051601f19818403018152919052805160209091012060a052506200028498505050505050505050565b80516001600160a01b0381168114620001f157600080fd5b919050565b600080600080608085870312156200020d57600080fd5b6200021885620001d9565b93506200022860208601620001d9565b92506200023860408601620001d9565b91506200024860608601620001d9565b905092959194509250565b6000825160005b818110156200027657602081860181015185830152016200025a565b506000920191825250919050565b60805160a05160c05160e05161010051610120516124986200030c600039600081816102260152610f9501526000818161026201526110240152600081816102c30152818161073d01528181610d6e0152610eb80152600081816101e70152610a630152600081816102fd01526107b00152600081816101b2015261093701526124986000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806379502c55116100a2578063a1a20ef211610071578063a1a20ef2146102e5578063abe93878146102f8578063c8d44eb21461031f578063d06a0d8214610332578063ffa1ad741461035957600080fd5b806379502c551461025d578063829d377014610284578063853b94a0146102975780639788ad55146102be57600080fd5b80633644e515116100de5780633644e515146101ad578063365a86fc146101e25780634379dbad14610221578063579bfc301461024857600080fd5b806301e83272146101105780631da4c2751461013a5780632d5d17fc1461016d578063335376cb1461018d575b600080fd5b61012361011e3660046118e9565b61037b565b604051610131929190611a3b565b60405180910390f35b61015d610148366004611adb565b60006020819052908152604090205460ff1681565b6040519015158152602001610131565b61018061017b366004611b34565b610634565b6040516101319190611be5565b6101a061019b366004611dbe565b6106fd565b6040516101319190611f61565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b61025b610256366004611f74565b610726565b005b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d4610292366004611f96565b6107ac565b6101d47f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a5970781565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d46102f3366004611fd8565b61087c565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b6101d461032d366004611fd8565b6108fc565b6101d47f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d81565b6101a060405180604001604052806003815260200162312e3360e81b81525081565b60006103856117f5565b60006103c689898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061063492505050565b90506104117f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707826040516020016103fd9190611be5565b604051602081830303815290604052610933565b92506104fb8b8b858a8a8a8a604051806101e001604052808a602001516001600160a01b031681526020018a6040015181526020018a60800151151581526020018a60a0015181526020018a60e0015181526020018a610100015181526020018a610120015181526020018a6101a0015164ffffffffff1681526020018a6101c001516001600160a01b031681526020018a6101e001516001600160a01b031681526020018a6102200151151581526020018a610240015181526020018a610260015181526020018a610280015181526020018a6102a001516001600160a01b03168152506109c4565b604051806101200160405280826102200151610517578c61051e565b826101e001515b6001600160a01b0316815260200182610220015161054157826101e00151610543565b8c5b6001600160a01b0316815260200161055f8361018001516111d7565b63ffffffff16815260200160405180608001604052808460000151600381111561058b5761058b6119d0565b815260200184602001516001600160a01b0316815260200184604001518152602001846060015181525081526020016105cc8360c001518460e0015161123a565b8152602001826101400151815260200182610160015162ffffff1681526020018261022001516105fd576000610604565b8261020001515b815260200182610220015161061e57826102000151610621565b60005b8152509150509850989650505050505050565b604080516102c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a0820152825190916106f79184018101908401612033565b92915050565b6060816040516020016107109190611be5565b6040516020818303038152906040529050919050565b60405163f79924a960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f79924a9906107769033908690869060040161217b565b600060405180830381600087803b15801561079057600080fd5b505af11580156107a4573d6000803e3d6000fd5b505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d836040516020016108049151815260200190565b60408051601f1981840301815290829052610822929160200161219c565b6040516020818303038152906040528051906020012060405160200161085f92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b6000610887826108fc565b90506108a48161089f61020085016101e086016121c2565b611272565b6108b661020083016101e084016121c2565b6001600160a01b0316817f94918c29cf820aa7f4261a4066a6933ed25b5aa16ee856d34f6ad5517eb44d22846040516108ef91906121df565b60405180910390a3919050565b60006106f77f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707836040516020016103fd91906121df565b60007f0000000000000000000000000000000000000000000000000000000000000000838360405160200161096992919061219c565b604051602081830303815290604052805190602001206040516020016109a692919061190160f01b81526002810192909252602282015260420190565b60405160208183030381529060405280519060200120905092915050565b806101c001516001600160a01b0316336001600160a01b031614610a18576101c081015160405163a4ce7f2960e01b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6101c081015160405163680cabbd60e11b81526001600160a01b0391821660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201527f00000000000000000000000000000000000000000000000000000000000000009091169063d019577a90604401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190612367565b610b25576101c0810151604051630b92eb2560e11b81526001600160a01b0390911660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946024820152604401610a0f565b6000849003610bc55760008681526020819052604090205460ff16610bc057610b8a8161012001518785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610bc0576101208101516040516301d2d55760e31b81526001600160a01b03909116600482015260248101879052604401610a0f565b610c67565b6000610be76040518060200160405280610be089898c611469565b90526107ac565b9050610c2f8261012001518286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610c65576101208201516040516301d2d55760e31b81526001600160a01b03909116600482015260248101829052604401610a0f565b505b876001600160a01b03168161012001516001600160a01b031603610ca9576040516326ab1a1d60e11b81526001600160a01b0389166004820152602401610a0f565b86600003610ce35761016081015115610cde57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b610d2c565b8061016001518714610d2c57610160810151151580610d055750806101400151155b15610d2c57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b8060e0015164ffffffffff164210610d6c5760e081015160405163aa2fd92560e01b815242600482015264ffffffffff9091166024820152604401610a0f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f291a62c826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610dcb9392919061217b565b602060405180830381865afa158015610de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0c9190612367565b610e3e57806101200151816101800151826101a00151604051632108c30560e11b8152600401610a0f9392919061217b565b6101008101516001600160a01b031615801590610e7257508061010001516001600160a01b0316886001600160a01b031614155b15610eaa57610100810151604051636075c95560e11b81526001600160a01b03808b1660048301529091166024820152604401610a0f565b8060a00151600003610f4c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f79924a9826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610f159392919061217b565b600060405180830381600087803b158015610f2f57600080fd5b505af1158015610f43573d6000803e3d6000fd5b50505050610ff4565b61012081015160c0820151608083015160a0840151604051638f8ea94960e01b81526001600160a01b0394851660048201526024810193909352604483019190915260648201527f000000000000000000000000000000000000000000000000000000000000000090911690638f8ea94990608401600060405180830381600087803b158015610fdb57600080fd5b505af1158015610fef573d6000803e3d6000fd5b505050505b8060400151156111cd578051604051630b7e49eb60e21b81526001600160a01b03918216600482015260009182917f000000000000000000000000000000000000000000000000000000000000000090911690632df927ac90602401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612384565b90506001600160a01b0381161561112f578251602084015160405163ec2ce34560e01b81526001600160a01b0384169263ec2ce345926110e7926004016001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015611104573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112891906123a1565b9150611196565b82516111429063f511231560e01b6114b5565b1561117d578251602084015160405163f511231560e01b81526001600160a01b039092169163f5112315916110e79160040190815260200190565b60405163f3c0936360e01b815260040160405180910390fd5b818360600151146111ca576060830151604051633840fc0160e01b8152610a0f918491600401918252602082015260400190565b50505b5050505050505050565b6000633b9aca008263ffffffff16116111ee575090565b428263ffffffff16111561120c576106f74263ffffffff84166123d0565b60405163e5084aed60e01b815263ffffffff808416600483015242166024820152604401610a0f565b919050565b61124261184e565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b336001600160a01b038216146112a657604051631144200360e31b81526001600160a01b0382166004820152602401610a0f565b506000908152602081905260409020805460ff19166001179055565b60006001600160a01b0384163b156113bd57600080856001600160a01b0316631626ba7e60e01b86866040516024016112fc9291906123e3565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161133a9190612404565b600060405180830381855afa9150503d8060008114611375576040519150601f19603f3d011682016040523d82523d6000602084013e61137a565b606091505b509150915081801561138d575080516020145b80156113b457508051630b135d3f60e11b906113b290830160209081019084016123a1565b145b92505050611462565b600080600084516041036113e55750505060208201516040830151606084015160001a61143c565b845160400361141e57602085015160408601519093506001600160ff1b038116925061141660ff82901c601b612420565b91505061143c565b845160405163058676ad60e31b8152600401610a0f91815260200190565b611448868285856114d1565b6001600160a01b0316876001600160a01b03161493505050505b9392505050565b600081815b848110156114ac576114988287878481811061148c5761148c612433565b905060200201356114f9565b9150806114a481612449565b91505061146e565b50949350505050565b60006114c083611528565b80156114625750611462838361155b565b60008060006114e2878787876115e4565b915091506114ef816116a8565b5095945050505050565b6000818310611515576000828152602084905260409020611462565b6000838152602083905260409020611462565b600061153b826301ffc9a760e01b61155b565b80156106f75750611554826001600160e01b031961155b565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156115cd575060208210155b80156115d95750600081115b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561161b575060009050600361169f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561166f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116985760006001925092505061169f565b9150600090505b94509492505050565b60008160048111156116bc576116bc6119d0565b036116c45750565b60018160048111156116d8576116d86119d0565b036117255760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a0f565b6002816004811115611739576117396119d0565b036117865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a0f565b600381600481111561179a5761179a6119d0565b036117f25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a0f565b50565b6040805161012081018252600080825260208201819052918101919091526060810161181f61184e565b815260200161182c61184e565b8152600060208201819052604082018190526060820181905260809091015290565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b6001600160a01b03811681146117f257600080fd5b803561123581611880565b60008083601f8401126118b257600080fd5b50813567ffffffffffffffff8111156118ca57600080fd5b6020830191508360208285010111156118e257600080fd5b9250929050565b60008060008060008060008060a0898b03121561190557600080fd5b883561191081611880565b975060208901359650604089013567ffffffffffffffff8082111561193457600080fd5b6119408c838d016118a0565b909850965060608b013591508082111561195957600080fd5b818b0191508b601f83011261196d57600080fd5b81358181111561197c57600080fd5b8c60208260051b850101111561199157600080fd5b6020830196508095505060808b01359150808211156119af57600080fd5b506119bc8b828c016118a0565b999c989b5096995094979396929594505050565b634e487b7160e01b600052602160045260246000fd5b60048110611a0457634e487b7160e01b600052602160045260246000fd5b9052565b611a138282516119e6565b6020818101516001600160a01b03169083015260408082015190830152606090810151910152565b82815281516001600160a01b03166020820152610200810160208301516001600160a01b038116604084015250604083015163ffffffff81166060840152506060830151611a8c6080840182611a08565b506080830151610100611aa181850183611a08565b60a085015161018085015260c085015162ffffff166101a085015260e08501516101c0850152909301516101e09092019190915292915050565b600060208284031215611aed57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102c0810167ffffffffffffffff81118282101715611b2e57611b2e611af4565b60405290565b600060208284031215611b4657600080fd5b813567ffffffffffffffff80821115611b5e57600080fd5b818401915084601f830112611b7257600080fd5b813581811115611b8457611b84611af4565b604051601f8201601f19908116603f01168101908382118183101715611bac57611bac611af4565b81604052828152876020848701011115611bc557600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006102c082019050611bf98284516119e6565b6020830151611c1360208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151611c3b608084018215159052565b5060a083015160a083015260c0830151611c6060c08401826001600160a01b03169052565b5060e083810151908301526101008084015190830152610120808401519083015261014080840151908301526101608084015162ffffff16908301526101808084015163ffffffff16908301526101a08084015164ffffffffff16908301526101c0808401516001600160a01b03908116918401919091526101e0808501518216908401526102008085015190840152610220808501511515908401526102408085015190840152610260808501519084015261028080850151908401526102a08085015191821681850152905b505092915050565b600481106117f257600080fd5b803561123581611d36565b80151581146117f257600080fd5b803561123581611d4e565b62ffffff811681146117f257600080fd5b803561123581611d67565b63ffffffff811681146117f257600080fd5b803561123581611d83565b64ffffffffff811681146117f257600080fd5b803561123581611da0565b60006102c08284031215611dd157600080fd5b611dd9611b0a565b611de283611d43565b8152611df060208401611895565b60208201526040830135604082015260608301356060820152611e1560808401611d5c565b608082015260a083013560a0820152611e3060c08401611895565b60c082015260e08381013590820152610100808401359082015261012080840135908201526101408084013590820152610160611e6e818501611d78565b90820152610180611e80848201611d95565b908201526101a0611e92848201611db3565b908201526101c0611ea4848201611895565b908201526101e0611eb6848201611895565b908201526102008381013590820152610220611ed3818501611d5c565b908201526102408381013590820152610260808401359082015261028080840135908201526102a0611f06818501611895565b908201529392505050565b60005b83811015611f2c578181015183820152602001611f14565b50506000910152565b60008151808452611f4d816020860160208601611f11565b601f01601f19169290920160200192915050565b6020815260006114626020830184611f35565b60008060408385031215611f8757600080fd5b50508035926020909101359150565b600060208284031215611fa857600080fd5b6040516020810181811067ffffffffffffffff82111715611fcb57611fcb611af4565b6040529135825250919050565b60006102c08284031215611feb57600080fd5b50919050565b805161123581611d36565b805161123581611880565b805161123581611d4e565b805161123581611d67565b805161123581611d83565b805161123581611da0565b60006102c0828403121561204657600080fd5b61204e611b0a565b61205783611ff1565b815261206560208401611ffc565b6020820152604083015160408201526060830151606082015261208a60808401612007565b608082015260a083015160a08201526120a560c08401611ffc565b60c082015260e083810151908201526101008084015190820152610120808401519082015261014080840151908201526101606120e3818501612012565b908201526101806120f584820161201d565b908201526101a0612107848201612028565b908201526101c0612119848201611ffc565b908201526101e061212b848201611ffc565b908201526102008381015190820152610220612148818501612007565b908201526102408381015190820152610260808401519082015261028080840151908201526102a0611f06818501611ffc565b6001600160a01b039390931683526020830191909152604082015260600190565b828152600082516121b4816020850160208701611f11565b919091016020019392505050565b6000602082840312156121d457600080fd5b813561146281611880565b6102c081016121f6826121f185611d43565b6119e6565b61220260208401611895565b6001600160a01b038116602084015250604083013560408301526060830135606083015261223260808401611d5c565b1515608083015260a0838101359083015261224f60c08401611895565b6001600160a01b031660c083015260e08381013590830152610100808401359083015261012080840135908301526101408084013590830152610160612296818501611d78565b62ffffff16908301526101806122ad848201611d95565b63ffffffff16908301526101a06122c5848201611db3565b64ffffffffff16908301526101c06122de848201611895565b6001600160a01b0316908301526101e06122f9848201611895565b6001600160a01b031690830152610200838101359083015261022061231f818501611d5c565b1515908301526102408381013590830152610260808401359083015261028080840135908301526102a0612354818501611895565b6001600160a01b03811684830152611d2e565b60006020828403121561237957600080fd5b815161146281611d4e565b60006020828403121561239657600080fd5b815161146281611880565b6000602082840312156123b357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106f7576106f76123ba565b8281526040602082015260006123fc6040830184611f35565b949350505050565b60008251612416818460208701611f11565b9190910192915050565b808201808211156106f7576106f76123ba565b634e487b7160e01b600052603260045260246000fd5b60006001820161245b5761245b6123ba565b506001019056fea2646970667358221220d1c79fb65b29e4e9487c9bdf24e8c0288745b6e97771284c74f63ca87e7f741164736f6c63430008100033","sourceMap":"421:8910:99:-:0;;;4929:240;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4051:867:98;;;;;;;;;;;;;;;;;;;;5158:7:99;;;;;;;;;;-1:-1:-1;;;5158:7:99;;;;-1:-1:-1;;;;;4249:18:98;;;;;4277:45;;;;;4332:27;;;;;4369:51;;;;4603:22;;5080:4:99;;5086:13;;5101:7;;5110:15;;4051:867:98;;5158:7:99;4484:95:98;;4603:22;;4051:867;;4603:22;;:::i;:::-;;;;;;;;;;;;;4593:33;;;;;;4667:7;4650:25;;;;;;;;:::i;:::-;;;;-1:-1:-1;;4650:25:98;;;;;;;;;4640:36;;4650:25;4640:36;;;;4460:280;;;1343:25:137;;;;1384:18;;1377:34;;;;1427:18;;;1420:34;;;;4690:13:98;1470:18:137;;;1463:34;4725:4:98;1513:19:137;;;1506:61;1315:19;;4460:280:98;;;;;;-1:-1:-1;;4460:280:98;;;;;;4450:291;;4460:280;4450:291;;;;4431:310;;4819:38;4795:115;;;1752:25:137;4871:29:98;1793:18:137;;;1786:34;1725:18;;4795:115:98;;;-1:-1:-1;;4795:115:98;;;;;;;;;4785:126;;4795:115;4785:126;;;;4752:159;;-1:-1:-1;421:8910:99;;-1:-1:-1;;;;;;;;;421:8910:99;14:177:137;93:13;;-1:-1:-1;;;;;135:31:137;;125:42;;115:70;;181:1;178;171:12;115:70;14:177;;;:::o;196:464::-;293:6;301;309;317;370:3;358:9;349:7;345:23;341:33;338:53;;;387:1;384;377:12;338:53;410:40;440:9;410:40;:::i;:::-;400:50;;469:49;514:2;503:9;499:18;469:49;:::i;:::-;459:59;;537:49;582:2;571:9;567:18;537:49;:::i;:::-;527:59;;605:49;650:2;639:9;635:18;605:49;:::i;:::-;595:59;;196:464;;;;;;;:::o;665:414::-;796:3;834:6;828:13;859:1;869:129;883:6;880:1;877:13;869:129;;;981:4;965:14;;;961:25;;955:32;942:11;;;935:53;898:12;869:129;;;-1:-1:-1;1053:1:137;1017:16;;1042:13;;;-1:-1:-1;1017:16:137;665:414;-1:-1:-1;665:414:137:o;1578:248::-;421:8910:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b506004361061010b5760003560e01c806379502c55116100a2578063a1a20ef211610071578063a1a20ef2146102e5578063abe93878146102f8578063c8d44eb21461031f578063d06a0d8214610332578063ffa1ad741461035957600080fd5b806379502c551461025d578063829d377014610284578063853b94a0146102975780639788ad55146102be57600080fd5b80633644e515116100de5780633644e515146101ad578063365a86fc146101e25780634379dbad14610221578063579bfc301461024857600080fd5b806301e83272146101105780631da4c2751461013a5780632d5d17fc1461016d578063335376cb1461018d575b600080fd5b61012361011e3660046118e9565b61037b565b604051610131929190611a3b565b60405180910390f35b61015d610148366004611adb565b60006020819052908152604090205460ff1681565b6040519015158152602001610131565b61018061017b366004611b34565b610634565b6040516101319190611be5565b6101a061019b366004611dbe565b6106fd565b6040516101319190611f61565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b61025b610256366004611f74565b610726565b005b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d4610292366004611f96565b6107ac565b6101d47f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a5970781565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d46102f3366004611fd8565b61087c565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b6101d461032d366004611fd8565b6108fc565b6101d47f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d81565b6101a060405180604001604052806003815260200162312e3360e81b81525081565b60006103856117f5565b60006103c689898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061063492505050565b90506104117f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707826040516020016103fd9190611be5565b604051602081830303815290604052610933565b92506104fb8b8b858a8a8a8a604051806101e001604052808a602001516001600160a01b031681526020018a6040015181526020018a60800151151581526020018a60a0015181526020018a60e0015181526020018a610100015181526020018a610120015181526020018a6101a0015164ffffffffff1681526020018a6101c001516001600160a01b031681526020018a6101e001516001600160a01b031681526020018a6102200151151581526020018a610240015181526020018a610260015181526020018a610280015181526020018a6102a001516001600160a01b03168152506109c4565b604051806101200160405280826102200151610517578c61051e565b826101e001515b6001600160a01b0316815260200182610220015161054157826101e00151610543565b8c5b6001600160a01b0316815260200161055f8361018001516111d7565b63ffffffff16815260200160405180608001604052808460000151600381111561058b5761058b6119d0565b815260200184602001516001600160a01b0316815260200184604001518152602001846060015181525081526020016105cc8360c001518460e0015161123a565b8152602001826101400151815260200182610160015162ffffff1681526020018261022001516105fd576000610604565b8261020001515b815260200182610220015161061e57826102000151610621565b60005b8152509150509850989650505050505050565b604080516102c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a0820152825190916106f79184018101908401612033565b92915050565b6060816040516020016107109190611be5565b6040516020818303038152906040529050919050565b60405163f79924a960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f79924a9906107769033908690869060040161217b565b600060405180830381600087803b15801561079057600080fd5b505af11580156107a4573d6000803e3d6000fd5b505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d836040516020016108049151815260200190565b60408051601f1981840301815290829052610822929160200161219c565b6040516020818303038152906040528051906020012060405160200161085f92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b6000610887826108fc565b90506108a48161089f61020085016101e086016121c2565b611272565b6108b661020083016101e084016121c2565b6001600160a01b0316817f94918c29cf820aa7f4261a4066a6933ed25b5aa16ee856d34f6ad5517eb44d22846040516108ef91906121df565b60405180910390a3919050565b60006106f77f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707836040516020016103fd91906121df565b60007f0000000000000000000000000000000000000000000000000000000000000000838360405160200161096992919061219c565b604051602081830303815290604052805190602001206040516020016109a692919061190160f01b81526002810192909252602282015260420190565b60405160208183030381529060405280519060200120905092915050565b806101c001516001600160a01b0316336001600160a01b031614610a18576101c081015160405163a4ce7f2960e01b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6101c081015160405163680cabbd60e11b81526001600160a01b0391821660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201527f00000000000000000000000000000000000000000000000000000000000000009091169063d019577a90604401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190612367565b610b25576101c0810151604051630b92eb2560e11b81526001600160a01b0390911660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946024820152604401610a0f565b6000849003610bc55760008681526020819052604090205460ff16610bc057610b8a8161012001518785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610bc0576101208101516040516301d2d55760e31b81526001600160a01b03909116600482015260248101879052604401610a0f565b610c67565b6000610be76040518060200160405280610be089898c611469565b90526107ac565b9050610c2f8261012001518286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610c65576101208201516040516301d2d55760e31b81526001600160a01b03909116600482015260248101829052604401610a0f565b505b876001600160a01b03168161012001516001600160a01b031603610ca9576040516326ab1a1d60e11b81526001600160a01b0389166004820152602401610a0f565b86600003610ce35761016081015115610cde57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b610d2c565b8061016001518714610d2c57610160810151151580610d055750806101400151155b15610d2c57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b8060e0015164ffffffffff164210610d6c5760e081015160405163aa2fd92560e01b815242600482015264ffffffffff9091166024820152604401610a0f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f291a62c826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610dcb9392919061217b565b602060405180830381865afa158015610de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0c9190612367565b610e3e57806101200151816101800151826101a00151604051632108c30560e11b8152600401610a0f9392919061217b565b6101008101516001600160a01b031615801590610e7257508061010001516001600160a01b0316886001600160a01b031614155b15610eaa57610100810151604051636075c95560e11b81526001600160a01b03808b1660048301529091166024820152604401610a0f565b8060a00151600003610f4c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f79924a9826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610f159392919061217b565b600060405180830381600087803b158015610f2f57600080fd5b505af1158015610f43573d6000803e3d6000fd5b50505050610ff4565b61012081015160c0820151608083015160a0840151604051638f8ea94960e01b81526001600160a01b0394851660048201526024810193909352604483019190915260648201527f000000000000000000000000000000000000000000000000000000000000000090911690638f8ea94990608401600060405180830381600087803b158015610fdb57600080fd5b505af1158015610fef573d6000803e3d6000fd5b505050505b8060400151156111cd578051604051630b7e49eb60e21b81526001600160a01b03918216600482015260009182917f000000000000000000000000000000000000000000000000000000000000000090911690632df927ac90602401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612384565b90506001600160a01b0381161561112f578251602084015160405163ec2ce34560e01b81526001600160a01b0384169263ec2ce345926110e7926004016001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015611104573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112891906123a1565b9150611196565b82516111429063f511231560e01b6114b5565b1561117d578251602084015160405163f511231560e01b81526001600160a01b039092169163f5112315916110e79160040190815260200190565b60405163f3c0936360e01b815260040160405180910390fd5b818360600151146111ca576060830151604051633840fc0160e01b8152610a0f918491600401918252602082015260400190565b50505b5050505050505050565b6000633b9aca008263ffffffff16116111ee575090565b428263ffffffff16111561120c576106f74263ffffffff84166123d0565b60405163e5084aed60e01b815263ffffffff808416600483015242166024820152604401610a0f565b919050565b61124261184e565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b336001600160a01b038216146112a657604051631144200360e31b81526001600160a01b0382166004820152602401610a0f565b506000908152602081905260409020805460ff19166001179055565b60006001600160a01b0384163b156113bd57600080856001600160a01b0316631626ba7e60e01b86866040516024016112fc9291906123e3565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161133a9190612404565b600060405180830381855afa9150503d8060008114611375576040519150601f19603f3d011682016040523d82523d6000602084013e61137a565b606091505b509150915081801561138d575080516020145b80156113b457508051630b135d3f60e11b906113b290830160209081019084016123a1565b145b92505050611462565b600080600084516041036113e55750505060208201516040830151606084015160001a61143c565b845160400361141e57602085015160408601519093506001600160ff1b038116925061141660ff82901c601b612420565b91505061143c565b845160405163058676ad60e31b8152600401610a0f91815260200190565b611448868285856114d1565b6001600160a01b0316876001600160a01b03161493505050505b9392505050565b600081815b848110156114ac576114988287878481811061148c5761148c612433565b905060200201356114f9565b9150806114a481612449565b91505061146e565b50949350505050565b60006114c083611528565b80156114625750611462838361155b565b60008060006114e2878787876115e4565b915091506114ef816116a8565b5095945050505050565b6000818310611515576000828152602084905260409020611462565b6000838152602083905260409020611462565b600061153b826301ffc9a760e01b61155b565b80156106f75750611554826001600160e01b031961155b565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156115cd575060208210155b80156115d95750600081115b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561161b575060009050600361169f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561166f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116985760006001925092505061169f565b9150600090505b94509492505050565b60008160048111156116bc576116bc6119d0565b036116c45750565b60018160048111156116d8576116d86119d0565b036117255760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a0f565b6002816004811115611739576117396119d0565b036117865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a0f565b600381600481111561179a5761179a6119d0565b036117f25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a0f565b50565b6040805161012081018252600080825260208201819052918101919091526060810161181f61184e565b815260200161182c61184e565b8152600060208201819052604082018190526060820181905260809091015290565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b6001600160a01b03811681146117f257600080fd5b803561123581611880565b60008083601f8401126118b257600080fd5b50813567ffffffffffffffff8111156118ca57600080fd5b6020830191508360208285010111156118e257600080fd5b9250929050565b60008060008060008060008060a0898b03121561190557600080fd5b883561191081611880565b975060208901359650604089013567ffffffffffffffff8082111561193457600080fd5b6119408c838d016118a0565b909850965060608b013591508082111561195957600080fd5b818b0191508b601f83011261196d57600080fd5b81358181111561197c57600080fd5b8c60208260051b850101111561199157600080fd5b6020830196508095505060808b01359150808211156119af57600080fd5b506119bc8b828c016118a0565b999c989b5096995094979396929594505050565b634e487b7160e01b600052602160045260246000fd5b60048110611a0457634e487b7160e01b600052602160045260246000fd5b9052565b611a138282516119e6565b6020818101516001600160a01b03169083015260408082015190830152606090810151910152565b82815281516001600160a01b03166020820152610200810160208301516001600160a01b038116604084015250604083015163ffffffff81166060840152506060830151611a8c6080840182611a08565b506080830151610100611aa181850183611a08565b60a085015161018085015260c085015162ffffff166101a085015260e08501516101c0850152909301516101e09092019190915292915050565b600060208284031215611aed57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102c0810167ffffffffffffffff81118282101715611b2e57611b2e611af4565b60405290565b600060208284031215611b4657600080fd5b813567ffffffffffffffff80821115611b5e57600080fd5b818401915084601f830112611b7257600080fd5b813581811115611b8457611b84611af4565b604051601f8201601f19908116603f01168101908382118183101715611bac57611bac611af4565b81604052828152876020848701011115611bc557600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006102c082019050611bf98284516119e6565b6020830151611c1360208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151611c3b608084018215159052565b5060a083015160a083015260c0830151611c6060c08401826001600160a01b03169052565b5060e083810151908301526101008084015190830152610120808401519083015261014080840151908301526101608084015162ffffff16908301526101808084015163ffffffff16908301526101a08084015164ffffffffff16908301526101c0808401516001600160a01b03908116918401919091526101e0808501518216908401526102008085015190840152610220808501511515908401526102408085015190840152610260808501519084015261028080850151908401526102a08085015191821681850152905b505092915050565b600481106117f257600080fd5b803561123581611d36565b80151581146117f257600080fd5b803561123581611d4e565b62ffffff811681146117f257600080fd5b803561123581611d67565b63ffffffff811681146117f257600080fd5b803561123581611d83565b64ffffffffff811681146117f257600080fd5b803561123581611da0565b60006102c08284031215611dd157600080fd5b611dd9611b0a565b611de283611d43565b8152611df060208401611895565b60208201526040830135604082015260608301356060820152611e1560808401611d5c565b608082015260a083013560a0820152611e3060c08401611895565b60c082015260e08381013590820152610100808401359082015261012080840135908201526101408084013590820152610160611e6e818501611d78565b90820152610180611e80848201611d95565b908201526101a0611e92848201611db3565b908201526101c0611ea4848201611895565b908201526101e0611eb6848201611895565b908201526102008381013590820152610220611ed3818501611d5c565b908201526102408381013590820152610260808401359082015261028080840135908201526102a0611f06818501611895565b908201529392505050565b60005b83811015611f2c578181015183820152602001611f14565b50506000910152565b60008151808452611f4d816020860160208601611f11565b601f01601f19169290920160200192915050565b6020815260006114626020830184611f35565b60008060408385031215611f8757600080fd5b50508035926020909101359150565b600060208284031215611fa857600080fd5b6040516020810181811067ffffffffffffffff82111715611fcb57611fcb611af4565b6040529135825250919050565b60006102c08284031215611feb57600080fd5b50919050565b805161123581611d36565b805161123581611880565b805161123581611d4e565b805161123581611d67565b805161123581611d83565b805161123581611da0565b60006102c0828403121561204657600080fd5b61204e611b0a565b61205783611ff1565b815261206560208401611ffc565b6020820152604083015160408201526060830151606082015261208a60808401612007565b608082015260a083015160a08201526120a560c08401611ffc565b60c082015260e083810151908201526101008084015190820152610120808401519082015261014080840151908201526101606120e3818501612012565b908201526101806120f584820161201d565b908201526101a0612107848201612028565b908201526101c0612119848201611ffc565b908201526101e061212b848201611ffc565b908201526102008381015190820152610220612148818501612007565b908201526102408381015190820152610260808401519082015261028080840151908201526102a0611f06818501611ffc565b6001600160a01b039390931683526020830191909152604082015260600190565b828152600082516121b4816020850160208701611f11565b919091016020019392505050565b6000602082840312156121d457600080fd5b813561146281611880565b6102c081016121f6826121f185611d43565b6119e6565b61220260208401611895565b6001600160a01b038116602084015250604083013560408301526060830135606083015261223260808401611d5c565b1515608083015260a0838101359083015261224f60c08401611895565b6001600160a01b031660c083015260e08381013590830152610100808401359083015261012080840135908301526101408084013590830152610160612296818501611d78565b62ffffff16908301526101806122ad848201611d95565b63ffffffff16908301526101a06122c5848201611db3565b64ffffffffff16908301526101c06122de848201611895565b6001600160a01b0316908301526101e06122f9848201611895565b6001600160a01b031690830152610200838101359083015261022061231f818501611d5c565b1515908301526102408381013590830152610260808401359083015261028080840135908301526102a0612354818501611895565b6001600160a01b03811684830152611d2e565b60006020828403121561237957600080fd5b815161146281611d4e565b60006020828403121561239657600080fd5b815161146281611880565b6000602082840312156123b357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106f7576106f76123ba565b8281526040602082015260006123fc6040830184611f35565b949350505050565b60008251612416818460208701611f11565b9190910192915050565b808201808211156106f7576106f76123ba565b634e487b7160e01b600052603260045260246000fd5b60006001820161245b5761245b6123ba565b506001019056fea2646970667358221220d1c79fb65b29e4e9487c9bdf24e8c0288745b6e97771284c74f63ca87e7f741164736f6c63430008100033","sourceMap":"421:8910:99:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6669:2659;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;2392:46:98;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;4587:14:137;;4580:22;4562:41;;4550:2;4535:18;2392:46:98;4422:187:137;6453:153:99;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6169:135::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1213:41:98:-;;;;;;;;12722:25:137;;;12710:2;12695:18;1213:41:98;12576:177:137;1322:27:98;;;;;;;;-1:-1:-1;;;;;12938:32:137;;;12920:51;;12908:2;12893:18;1322:27:98;12758:219:137;1445:49:98;;;;;5840:137;;;;;;:::i;:::-;;:::i;:::-;;1406:33;;;;;5290:322;;;;;;:::i;:::-;;:::i;605:600:99:-;;649:556;605:600;;1355:45:98;;;;;5745:273:99;;;;;;:::i;:::-;;:::i;1260:55:98:-;;;;;5338:164:99;;;;;;:::i;:::-;;:::i;1501:108:98:-;;1550:59;1501:108;;490:38:99;;;;;;;;;;;;;;;-1:-1:-1;;;490:38:99;;;;;6669:2659;6909:20;6931:36;;:::i;:::-;7011:24;7038:32;7057:12;;7038:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7038:18:99;;-1:-1:-1;;;7038:32:99:i;:::-;7011:59;;7126:57;649:556;7173:8;7162:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;7126:16;:57::i;:::-;7111:72;;7228:1076;7257:8;7279:17;7310:12;7336:22;;7372:9;;7395:899;;;;;;;;7445:8;:26;;;-1:-1:-1;;;;;7395:899:99;;;;;7503:8;:21;;;7395:899;;;;7575:8;:40;;;7395:899;;;;;;7661:8;:35;;;7395:899;;;;7728:8;:21;;;7395:899;;;;7789:8;:29;;;7395:899;;;;7854:8;:25;;;7395:899;;;;7909:8;:19;;;7395:899;;;;;;7963:8;:24;;;-1:-1:-1;;;;;7395:899:99;;;;;8015:8;:17;;;-1:-1:-1;;;;;7395:899:99;;;;;8059:8;:16;;;7395:899;;;;;;8112:8;:26;;;7395:899;;;;8168:8;:19;;;7395:899;;;;8212:8;:14;;;7395:899;;;;8258:8;:21;;;-1:-1:-1;;;;;7395:899:99;;;;7228:15;:1076::i;:::-;8363:958;;;;;;;;8405:8;:16;;;:47;;8444:8;8405:47;;;8424:8;:17;;;8405:47;-1:-1:-1;;;;;8363:958:99;;;;;8476:8;:16;;;:47;;8506:8;:17;;;8476:47;;;8495:8;8476:47;-1:-1:-1;;;;;8363:958:99;;;;;8547:41;8564:8;:23;;;8547:16;:41::i;:::-;8363:958;;;;;;8614:239;;;;;;;;8659:8;:27;;;8614:239;;;;;;;;:::i;:::-;;;;;8718:8;:26;;;-1:-1:-1;;;;;8614:239:99;;;;;8766:8;:21;;;8614:239;;;;8813:8;:25;;;8614:239;;;8363:958;;;;8875:133;8924:8;:22;;;8972:8;:21;;;8875:16;:133::i;:::-;8363:958;;;;9043:8;:28;;;8363:958;;;;9106:8;:28;;;8363:958;;;;;;9164:8;:16;;;:57;;9219:1;9164:57;;;9183:8;:25;;;9164:57;8363:958;;;;9253:8;:16;;;:57;;9285:8;:25;;;9253:57;;;9280:1;9253:57;8363:958;;;8351:970;;6969:2359;6669:2659;;;;;;;;;;;:::o;6453:153::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6563:36:99;;-1:-1:-1;;6563:36:99;;;;;;;;;;:::i;:::-;6556:43;6453:153;-1:-1:-1;;6453:153:99:o;6169:135::-;6246:12;6288:8;6277:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;6270:27;;6169:135;;;:::o;5840:137:98:-;5915:55;;-1:-1:-1;;;5915:55:98;;-1:-1:-1;;;;;5915:12:98;:24;;;;:55;;5940:10;;5952;;5964:5;;5915:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5840:137;;:::o;5290:322::-;5377:7;5454:30;1550:59;5565:13;5554:25;;;;;;18336:13:137;18318:32;;18306:2;18291:18;;18108:248;5554:25:98;;;;-1:-1:-1;;5554:25:98;;;;;;;;;;5496:97;;;5554:25;5496:97;;:::i;:::-;;;;;;;;;;;;;5486:108;;;;;;5413:191;;;;;;;;-1:-1:-1;;;18983:27:137;;19035:1;19026:11;;19019:27;;;;19071:2;19062:12;;19055:28;19108:2;19099:12;;18725:392;5413:191:98;;;;;;;;;;;;;5403:202;;;;;;5396:209;;5290:322;;;:::o;5745:273:99:-;5813:20;5860:25;5876:8;5860:15;:25::i;:::-;5845:40;-1:-1:-1;5895:46:99;5845:40;5923:17;;;;;;;;:::i;:::-;5895:13;:46::i;:::-;5983:17;;;;;;;;:::i;:::-;-1:-1:-1;;;;;5956:55:99;5969:12;5956:55;6002:8;5956:55;;;;;;:::i;:::-;;;;;;;;5745:273;;;:::o;5338:164::-;5412:7;5438:57;649:556;5485:8;5474:20;;;;;;;;:::i;7195:332:98:-;7322:7;7399:16;7461;7479:15;7427:81;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7417:92;;;;;;7358:161;;;;;;;;-1:-1:-1;;;18983:27:137;;19035:1;19026:11;;19019:27;;;;19071:2;19062:12;;19055:28;19108:2;19099:12;;18725:392;7358:161:98;;;;;;;;;;;;;7348:172;;;;;;7341:179;;7195:332;;;;:::o;9037:5154::-;9350:8;:21;;;-1:-1:-1;;;;;9336:35:98;:10;-1:-1:-1;;;;;9336:35:98;;9332:155;;9452:21;;;;9394:82;;-1:-1:-1;;;9394:82:98;;9426:10;9394:82;;;22256:34:137;-1:-1:-1;;;;;22326:15:137;;;22306:18;;;22299:43;22191:18;;9394:82:98;;;;;;;;9332:155;9512:21;;;;9501:57;;-1:-1:-1;;;9501:57:98;;-1:-1:-1;;;;;22545:32:137;;;9501:57:98;;;22527:51:137;266:28:82;22594:18:137;;;22587:34;9501:3:98;:10;;;;;;22500:18:137;;9501:57:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9496:178;;9610:21;;;;9581:82;;-1:-1:-1;;;9581:82:98;;-1:-1:-1;;;;;22545:32:137;;;9581:82:98;;;22527:51:137;266:28:82;22594:18:137;;;22587:34;22500:18;;9581:82:98;22353:274:137;9496:178:98;9786:1;9753:34;;;9749:1025;;9849:13;:27;;;;;;;;;;;;;9844:293;;9901:83;9941:8;:17;;;9960:12;9974:9;;9901:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9901:39:98;;-1:-1:-1;;;9901:83:98:i;:::-;9896:227;;10062:17;;;;10015:89;;-1:-1:-1;;;10015:89:98;;-1:-1:-1;;;;;22545:32:137;;;10015:89:98;;;22527:51:137;22594:18;;;22587:34;;;22500:18;;10015:89:98;22353:274:137;9896:227:98;9749:1025;;;10206:25;10234:287;10272:235;;;;;;;;10333:155;10399:22;;10453:12;10333:32;:155::i;:::-;10272:235;;10234:20;:287::i;:::-;10206:315;;10540:88;10580:8;:17;;;10599;10618:9;;10540:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10540:39:98;;-1:-1:-1;;;10540:88:98:i;:::-;10535:229;;10702:17;;;;10655:94;;-1:-1:-1;;;10655:94:98;;-1:-1:-1;;;;;22545:32:137;;;10655:94:98;;;22527:51:137;22594:18;;;22587:34;;;22500:18;;10655:94:98;22353:274:137;10535:229:98;10153:621;9749:1025;10851:8;-1:-1:-1;;;;;10830:29:98;:8;:17;;;-1:-1:-1;;;;;10830:29:98;;10826:104;;10882:37;;-1:-1:-1;;;10882:37:98;;-1:-1:-1;;;;;12938:32:137;;10882:37:98;;;12920:51:137;12893:18;;10882:37:98;12758:219:137;10826:104:98;10982:17;11003:1;10982:22;10978:500;;11024:26;;;;:31;11020:152;;11128:8;:26;;;11082:75;;-1:-1:-1;;;11082:75:98;;;;;;12722:25:137;;12710:2;12695:18;;12576:177;11020:152:98;10978:500;;;11227:8;:26;;;11206:17;:47;11202:266;;11277:26;;;;:31;;;:52;;;11313:8;:16;;;11312:17;11277:52;11273:181;;;11406:8;:26;;;11360:75;;-1:-1:-1;;;11360:75:98;;;;;;12722:25:137;;12710:2;12695:18;;12576:177;11273:181:98;11552:8;:19;;;11533:38;;:15;:38;11529:146;;11642:19;;;;11594:70;;-1:-1:-1;;;11594:70:98;;11613:15;11594:70;;;23445:25:137;23518:12;23506:25;;;23486:18;;;23479:53;23418:18;;11594:70:98;23272:266:137;11529:146:98;11731:12;-1:-1:-1;;;;;11731:26:98;;11758:8;:17;;;11777:8;:19;;;11798:8;:14;;;11731:82;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11726:296;;11891:8;:17;;;11938:8;:19;;;11982:8;:14;;;11836:175;;-1:-1:-1;;;11836:175:98;;;;;;;;;;:::i;11726:296::-;12095:24;;;;-1:-1:-1;;;;;12095:38:98;;;;;:78;;;12149:8;:24;;;-1:-1:-1;;;;;12137:36:98;:8;-1:-1:-1;;;;;12137:36:98;;;12095:78;12091:198;;;12251:24;;;;12196:82;;-1:-1:-1;;;12196:82:98;;-1:-1:-1;;;;;22274:15:137;;;12196:82:98;;;22256:34:137;22326:15;;;22306:18;;;22299:43;22191:18;;12196:82:98;22044:304:137;12091:198:98;12303:8;:29;;;12336:1;12303:34;12299:554;;12438:12;-1:-1:-1;;;;;12438:24:98;;12463:8;:17;;;12482:8;:19;;;12503:8;:14;;;12438:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12299:554;;;12730:17;;;;12749:25;;;;12776:21;;;;12799:29;;;;12684:158;;-1:-1:-1;;;12684:158:98;;-1:-1:-1;;;;;23792:32:137;;;12684:158:98;;;23774:51:137;23841:18;;;23834:34;;;;23884:18;;;23877:34;;;;23927:18;;;23920:34;12684:14:98;:28;;;;;;23746:19:137;;12684:158:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12299:554;12923:8;:40;;;12919:1266;;;13091:26;;13056:62;;-1:-1:-1;;;13056:62:98;;-1:-1:-1;;;;;12938:32:137;;;13056:62:98;;;12920:51:137;12979:26:98;;;;13056:6;:34;;;;;;12893:18:137;;13056:62:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13019:99;-1:-1:-1;;;;;;13136:31:98;;;13132:717;;13319:26;;13356:21;;;;13257:139;;-1:-1:-1;;;13257:139:98;;-1:-1:-1;;;;;13257:32:98;;;;;:139;;;;-1:-1:-1;;;;;22545:32:137;;;;22527:51;;22609:2;22594:18;;22587:34;22515:2;22500:18;;22353:274;13257:139:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13236:160;;13132:717;;;13453:26;;13421:87;;-1:-1:-1;;;13421:31:98;:87::i;:::-;13417:432;;;13602:26;;13650:21;;;;13593:79;;-1:-1:-1;;;13593:79:98;;-1:-1:-1;;;;;13593:56:98;;;;;;:79;;;;12722:25:137;;;12710:2;12695:18;;12576:177;13417:432:98;13801:33;;-1:-1:-1;;;13801:33:98;;;;;;;;;;;13417:432;13906:18;13867:8;:35;;;:57;13863:312;;14106:35;;;;13991:169;;-1:-1:-1;;;13991:169:98;;;;14056:18;;13991:169;;24898:25:137;;;24954:2;24939:18;;24932:34;24886:2;24871:18;;24724:248;13863:312:98;12965:1220;;12919:1266;9037:5154;;;;;;;;:::o;8155:478::-;8227:6;8267:3;8249:14;:21;;;8245:382;;-1:-1:-1;8326:14:98;8155:478::o;8245:382::-;8378:15;8361:14;:32;;;8357:270;;;8452:41;8478:15;8452:23;;;:41;:::i;8357:270::-;8532:84;;-1:-1:-1;;;8532:84:98;;25422:10:137;25459:15;;;8532:84:98;;;25441:34:137;8597:15:98;25511::137;25491:18;;;25484:43;25385:18;;8532:84:98;25242:291:137;8357:270:98;8155:478;;;:::o;2542:160:0:-;2618:12;;:::i;:::-;-1:-1:-1;2649:46:0;;;;;;;;-1:-1:-1;2649:46:0;;;-1:-1:-1;;;;;2649:46:0;;;;;;;;;;;;;;;;;;;;2542:160::o;7748:238:98:-;7834:10;-1:-1:-1;;;;;7834:22:98;;;7830:105;;7879:45;;-1:-1:-1;;;7879:45:98;;-1:-1:-1;;;;;12938:32:137;;7879:45:98;;;12920:51:137;12893:18;;7879:45:98;12758:219:137;7830:105:98;-1:-1:-1;7945:13:98;:27;;;;;;;;;;:34;;-1:-1:-1;;7945:34:98;7975:4;7945:34;;;7748:238::o;1541:1696:92:-;1677:4;-1:-1:-1;;;;;1759:18:92;;;:22;1755:1476;;1798:12;1812:19;1835:6;-1:-1:-1;;;;;1835:17:92;1893:34;;;1929:4;1935:9;1870:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1870:75:92;;;;;;;;;;;;;;-1:-1:-1;;;;;1870:75:92;-1:-1:-1;;;;;;1870:75:92;;;;;;;;;;1835:124;;;;1870:75;1835:124;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1797:162;;;;1996:7;:46;;;;;2023:6;:13;2040:2;2023:19;1996:46;:142;;;;-1:-1:-1;2062:29:92;;-1:-1:-1;;;2103:34:92;2062:29;;;;;;;;;;;;:::i;:::-;:76;1996:142;1973:165;;;;;;1755:1476;2226:9;2249;2272:7;2348:9;:16;2368:2;2348:22;2344:817;;-1:-1:-1;;;2447:4:92;2432:20;;2426:27;2500:4;2485:20;;2479:27;2561:4;2546:20;;2540:27;2537:1;2532:36;2344:817;;;2686:9;:16;2706:2;2686:22;2682:479;;2814:4;2799:20;;2793:27;2868:4;2853:20;;2847:27;2793;;-1:-1:-1;;;;;;2914:80:92;;;-1:-1:-1;3022:25:92;3038:3;3023:18;;;3045:2;3022:25;:::i;:::-;3012:36;;2710:353;2682:479;;;3127:9;:16;3094:52;;-1:-1:-1;;;3094:52:92;;;;;;12722:25:137;;12710:2;12695:18;;12576:177;2682:479:92;3192:28;3206:4;3212:1;3215;3218;3192:13;:28::i;:::-;-1:-1:-1;;;;;3182:38:92;:6;-1:-1:-1;;;;;3182:38:92;;3175:45;;;;;1755:1476;1541:1696;;;;;:::o;2331:300:66:-;2424:7;2466:4;2424:7;2480:116;2500:16;;;2480:116;;;2552:33;2562:12;2576:5;;2582:1;2576:8;;;;;;;:::i;:::-;;;;;;;2552:9;:33::i;:::-;2537:48;-1:-1:-1;2518:3:66;;;;:::i;:::-;;;;2480:116;;;-1:-1:-1;2612:12:66;2331:300;-1:-1:-1;;;;2331:300:66:o;1349:282:68:-;1436:4;1543:23;1558:7;1543:14;:23::i;:::-;:81;;;;;1570:54;1603:7;1612:11;1570:32;:54::i;6598:232:65:-;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:65;6598:232;-1:-1:-1;;;;;6598:232:65:o;9205:147:66:-;9268:7;9298:1;9294;:5;:51;;9426:13;9517:15;;;9552:4;9545:15;;;9598:4;9582:21;;9294:51;;;9426:13;9517:15;;;9552:4;9545:15;;;9598:4;9582:21;;9302:20;9358:261;704:427:68;768:4;975:68;1008:7;-1:-1:-1;;;975:32:68;:68::i;:::-;:149;;;;-1:-1:-1;1060:64:68;1093:7;-1:-1:-1;;;;;;1060:32:68;:64::i;:::-;1059:65;956:168;704:427;-1:-1:-1;;704:427:68:o;4421:647::-;4592:71;;;-1:-1:-1;;;;;;26687:33:137;;4592:71:68;;;;26669:52:137;;;;4592:71:68;;;;;;;;;;26642:18:137;;;;4592:71:68;;;;;;;;;-1:-1:-1;;;;;4592:71:68;-1:-1:-1;;;4592:71:68;;;4871:20;;4523:4;;4592:71;4523:4;;;;;;4592:71;4523:4;;4871:20;4836:7;4829:5;4818:86;4807:97;;4931:16;4917:30;;4981:4;4975:11;4960:26;;5013:7;:29;;;;;5038:4;5024:10;:18;;5013:29;:48;;;;;5060:1;5046:11;:15;5013:48;5006:55;4421:647;-1:-1:-1;;;;;;;4421:647:68:o;5009:1456:65:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:65;;-1:-1:-1;6123:30:65;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;26959:25:137;;;27032:4;27020:17;;27000:18;;;26993:45;;;;27054:18;;;27047:34;;;27097:18;;;27090:34;;;6276:24:65;;26931:19:137;;6276:24:65;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:65;;-1:-1:-1;;6276:24:65;;;-1:-1:-1;;;;;;;6314:20:65;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:65;;-1:-1:-1;5009:1456:65;;;;;;;;:::o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:65;;27337:2:137;788:34:65;;;27319:21:137;27376:2;27356:18;;;27349:30;27415:26;27395:18;;;27388:54;27459:18;;788:34:65;27135:348:137;730:345:65;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:65;;27690:2:137;903:41:65;;;27672:21:137;27729:2;27709:18;;;27702:30;27768:33;27748:18;;;27741:61;27819:18;;903:41:65;27488:355:137;839:236:65;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:65;;28050:2:137;1020:44:65;;;28032:21:137;28089:2;28069:18;;;28062:30;28128:34;28108:18;;;28101:62;-1:-1:-1;;;28179:18:137;;;28172:32;28221:19;;1020:44:65;27848:398:137;961:114:65;570:511;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:137:-;-1:-1:-1;;;;;89:31:137;;79:42;;69:70;;135:1;132;125:12;150:134;218:20;;247:31;218:20;247:31;:::i;289:347::-;340:8;350:6;404:3;397:4;389:6;385:17;381:27;371:55;;422:1;419;412:12;371:55;-1:-1:-1;445:20:137;;488:18;477:30;;474:50;;;520:1;517;510:12;474:50;557:4;549:6;545:17;533:29;;609:3;602:4;593:6;585;581:19;577:30;574:39;571:59;;;626:1;623;616:12;571:59;289:347;;;;;:::o;641:1394::-;785:6;793;801;809;817;825;833;841;894:3;882:9;873:7;869:23;865:33;862:53;;;911:1;908;901:12;862:53;950:9;937:23;969:31;994:5;969:31;:::i;:::-;1019:5;-1:-1:-1;1071:2:137;1056:18;;1043:32;;-1:-1:-1;1126:2:137;1111:18;;1098:32;1149:18;1179:14;;;1176:34;;;1206:1;1203;1196:12;1176:34;1245:58;1295:7;1286:6;1275:9;1271:22;1245:58;:::i;:::-;1322:8;;-1:-1:-1;1219:84:137;-1:-1:-1;1410:2:137;1395:18;;1382:32;;-1:-1:-1;1426:16:137;;;1423:36;;;1455:1;1452;1445:12;1423:36;1493:8;1482:9;1478:24;1468:34;;1540:7;1533:4;1529:2;1525:13;1521:27;1511:55;;1562:1;1559;1552:12;1511:55;1602:2;1589:16;1628:2;1620:6;1617:14;1614:34;;;1644:1;1641;1634:12;1614:34;1697:7;1692:2;1682:6;1679:1;1675:14;1671:2;1667:23;1663:32;1660:45;1657:65;;;1718:1;1715;1708:12;1657:65;1749:2;1745;1741:11;1731:21;;1771:6;1761:16;;;1830:3;1819:9;1815:19;1802:33;1786:49;;1860:2;1850:8;1847:16;1844:36;;;1876:1;1873;1866:12;1844:36;;1915:60;1967:7;1956:8;1945:9;1941:24;1915:60;:::i;:::-;641:1394;;;;-1:-1:-1;641:1394:137;;-1:-1:-1;641:1394:137;;;;;;1994:8;-1:-1:-1;;;641:1394:137:o;2248:127::-;2309:10;2304:3;2300:20;2297:1;2290:31;2340:4;2337:1;2330:15;2364:4;2361:1;2354:15;2380:236;2460:1;2453:5;2450:12;2440:143;;2505:10;2500:3;2496:20;2493:1;2486:31;2540:4;2537:1;2530:15;2568:4;2565:1;2558:15;2440:143;2592:18;;2380:236::o;2621:302::-;2680:43;2719:3;2711:5;2705:12;2680:43;:::i;:::-;2776:4;2765:16;;;2759:23;-1:-1:-1;;;;;2755:49:137;2739:14;;;2732:73;2854:4;2843:16;;;2837:23;2821:14;;;2814:47;2910:4;2899:16;;;2893:23;2877:14;;2870:47;2621:302::o;3025:1111::-;3248:25;;;3301:13;;-1:-1:-1;;;;;2106:31:137;3331:2;3316:18;;2094:44;3235:3;3220:19;;3382:2;3370:15;;3364:22;-1:-1:-1;;;;;2106:31:137;;3443:2;3428:18;;2094:44;-1:-1:-1;3496:2:137;3484:15;;3478:22;2225:10;2214:22;;3558:2;3543:18;;2202:35;3509:53;3611:2;3603:6;3599:15;3593:22;3624:60;3679:3;3668:9;3664:19;3648:14;3624:60;:::i;:::-;;3733:3;3725:6;3721:16;3715:23;3757:3;3769:59;3824:2;3813:9;3809:18;3793:14;3769:59;:::i;:::-;3883:4;3871:17;;3865:24;3859:3;3844:19;;3837:53;3939:4;3927:17;;3921:24;3004:8;2993:20;4003:3;3988:19;;2981:33;4063:4;4051:17;;4045:24;4039:3;4024:19;;4017:53;4113:15;;;4107:22;4101:3;4086:19;;;4079:51;;;;3025:1111;;-1:-1:-1;;3025:1111:137:o;4141:180::-;4200:6;4253:2;4241:9;4232:7;4228:23;4224:32;4221:52;;;4269:1;4266;4259:12;4221:52;-1:-1:-1;4292:23:137;;4141:180;-1:-1:-1;4141:180:137:o;4614:127::-;4675:10;4670:3;4666:20;4663:1;4656:31;4706:4;4703:1;4696:15;4730:4;4727:1;4720:15;4746:247;4813:2;4807:9;4855:3;4843:16;;4889:18;4874:34;;4910:22;;;4871:62;4868:88;;;4936:18;;:::i;:::-;4972:2;4965:22;4746:247;:::o;4998:921::-;5066:6;5119:2;5107:9;5098:7;5094:23;5090:32;5087:52;;;5135:1;5132;5125:12;5087:52;5175:9;5162:23;5204:18;5245:2;5237:6;5234:14;5231:34;;;5261:1;5258;5251:12;5231:34;5299:6;5288:9;5284:22;5274:32;;5344:7;5337:4;5333:2;5329:13;5325:27;5315:55;;5366:1;5363;5356:12;5315:55;5402:2;5389:16;5424:2;5420;5417:10;5414:36;;;5430:18;;:::i;:::-;5505:2;5499:9;5473:2;5559:13;;-1:-1:-1;;5555:22:137;;;5579:2;5551:31;5547:40;5535:53;;;5603:18;;;5623:22;;;5600:46;5597:72;;;5649:18;;:::i;:::-;5689:10;5685:2;5678:22;5724:2;5716:6;5709:18;5764:7;5759:2;5754;5750;5746:11;5742:20;5739:33;5736:53;;;5785:1;5782;5775:12;5736:53;5841:2;5836;5832;5828:11;5823:2;5815:6;5811:15;5798:46;5886:1;5864:15;;;5881:2;5860:24;5853:35;;;;-1:-1:-1;5868:6:137;4998:921;-1:-1:-1;;;;;4998:921:137:o;6025:2446::-;6171:4;6213:3;6202:9;6198:19;6190:27;;6226:50;6266:9;6257:6;6251:13;6226:50;:::i;:::-;6323:4;6315:6;6311:17;6305:24;6338:54;6386:4;6375:9;6371:20;6357:12;-1:-1:-1;;;;;2106:31:137;2094:44;;2040:104;6338:54;;6448:4;6440:6;6436:17;6430:24;6423:4;6412:9;6408:20;6401:54;6511:4;6503:6;6499:17;6493:24;6486:4;6475:9;6471:20;6464:54;6567:4;6559:6;6555:17;6549:24;6582:53;6629:4;6618:9;6614:20;6598:14;4396:13;4389:21;4377:34;;4326:91;6582:53;;6691:4;6683:6;6679:17;6673:24;6666:4;6655:9;6651:20;6644:54;6747:4;6739:6;6735:17;6729:24;6762:56;6812:4;6801:9;6797:20;6781:14;-1:-1:-1;;;;;2106:31:137;2094:44;;2040:104;6762:56;-1:-1:-1;6874:4:137;6862:17;;;6856:24;6834:20;;;6827:54;6900:6;6948:15;;;6942:22;6922:18;;;6915:50;6984:6;7032:15;;;7026:22;7006:18;;;6999:50;7068:6;7116:15;;;7110:22;7090:18;;;7083:50;7152:6;7195:15;;;7189:22;3004:8;2993:20;7254:18;;;2981:33;7292:6;7335:15;;;7329:22;2225:10;2214:22;7394:18;;;2202:35;7432:6;7475:15;;;7469:22;6000:12;5989:24;7534:18;;;5977:37;7572:6;7615:15;;;7609:22;-1:-1:-1;;;;;2106:31:137;;;7675:18;;;2094:44;;;;7713:6;7756:15;;;7750:22;2106:31;;7816:18;;;2094:44;7854:6;7902:15;;;7896:22;7876:18;;;7869:50;7939:6;7982:16;;;7976:23;4396:13;4389:21;8040:19;;;4377:34;8080:6;8129:16;;;8123:23;8102:19;;;8095:52;8167:6;8216:16;;;8210:23;8189:19;;;8182:52;8254:6;8303:16;;;8297:23;8276:19;;;8269:52;8341:6;8384:16;;;8378:23;2106:31;;;8445:19;;;2094:44;8341:6;8410:55;;;6025:2446;;;;:::o;8476:107::-;8557:1;8550:5;8547:12;8537:40;;8573:1;8570;8563:12;8588:146;8662:20;;8691:37;8662:20;8691:37;:::i;8739:118::-;8825:5;8818:13;8811:21;8804:5;8801:32;8791:60;;8847:1;8844;8837:12;8862:128;8927:20;;8956:28;8927:20;8956:28;:::i;8995:119::-;9080:8;9073:5;9069:20;9062:5;9059:31;9049:59;;9104:1;9101;9094:12;9119:132;9186:20;;9215:30;9186:20;9215:30;:::i;9256:121::-;9341:10;9334:5;9330:22;9323:5;9320:33;9310:61;;9367:1;9364;9357:12;9382:132;9449:20;;9478:30;9449:20;9478:30;:::i;9519:123::-;9604:12;9597:5;9593:24;9586:5;9583:35;9573:63;;9632:1;9629;9622:12;9647:132;9714:20;;9743:30;9714:20;9743:30;:::i;9784:2035::-;9870:6;9923:3;9911:9;9902:7;9898:23;9894:33;9891:53;;;9940:1;9937;9930:12;9891:53;9966:17;;:::i;:::-;10006:35;10031:9;10006:35;:::i;:::-;9999:5;9992:50;10074:38;10108:2;10097:9;10093:18;10074:38;:::i;:::-;10069:2;10062:5;10058:14;10051:62;10173:2;10162:9;10158:18;10145:32;10140:2;10133:5;10129:14;10122:56;10238:2;10227:9;10223:18;10210:32;10205:2;10198:5;10194:14;10187:56;10276:36;10307:3;10296:9;10292:19;10276:36;:::i;:::-;10270:3;10263:5;10259:15;10252:61;10374:3;10363:9;10359:19;10346:33;10340:3;10333:5;10329:15;10322:58;10413:39;10447:3;10436:9;10432:19;10413:39;:::i;:::-;10407:3;10396:15;;10389:64;10514:3;10499:19;;;10486:33;10469:15;;;10462:58;10539:3;10587:18;;;10574:32;10558:14;;;10551:56;10626:3;10674:18;;;10661:32;10645:14;;;10638:56;10713:3;10761:18;;;10748:32;10732:14;;;10725:56;10800:3;10835:37;10853:18;;;10835:37;:::i;:::-;10819:14;;;10812:61;10892:3;10927:37;10945:18;;;10927:37;:::i;:::-;10911:14;;;10904:61;10984:3;11019:37;11037:18;;;11019:37;:::i;:::-;11003:14;;;10996:61;11076:3;11111:38;11130:18;;;11111:38;:::i;:::-;11095:14;;;11088:62;11169:3;11204:38;11223:18;;;11204:38;:::i;:::-;11188:14;;;11181:62;11262:3;11310:18;;;11297:32;11281:14;;;11274:56;11350:3;11386:36;11402:19;;;11386:36;:::i;:::-;11369:15;;;11362:61;11443:3;11492:19;;;11479:33;11462:15;;;11455:58;11533:3;11582:19;;;11569:33;11552:15;;;11545:58;11623:3;11672:19;;;11659:33;11642:15;;;11635:58;11713:3;11749:39;11768:19;;;11749:39;:::i;:::-;11732:15;;;11725:64;11736:5;9784:2035;-1:-1:-1;;;9784:2035:137:o;11824:250::-;11909:1;11919:113;11933:6;11930:1;11927:13;11919:113;;;12009:11;;;12003:18;11990:11;;;11983:39;11955:2;11948:10;11919:113;;;-1:-1:-1;;12066:1:137;12048:16;;12041:27;11824:250::o;12079:270::-;12120:3;12158:5;12152:12;12185:6;12180:3;12173:19;12201:76;12270:6;12263:4;12258:3;12254:14;12247:4;12240:5;12236:16;12201:76;:::i;:::-;12331:2;12310:15;-1:-1:-1;;12306:29:137;12297:39;;;;12338:4;12293:50;;12079:270;-1:-1:-1;;12079:270:137:o;12354:217::-;12501:2;12490:9;12483:21;12464:4;12521:44;12561:2;12550:9;12546:18;12538:6;12521:44;:::i;13217:248::-;13285:6;13293;13346:2;13334:9;13325:7;13321:23;13317:32;13314:52;;;13362:1;13359;13352:12;13314:52;-1:-1:-1;;13385:23:137;;;13455:2;13440:18;;;13427:32;;-1:-1:-1;13217:248:137:o;13697:445::-;13788:6;13841:2;13829:9;13820:7;13816:23;13812:32;13809:52;;;13857:1;13854;13847:12;13809:52;13890:2;13884:9;13932:2;13924:6;13920:15;14001:6;13989:10;13986:22;13965:18;13953:10;13950:34;13947:62;13944:88;;;14012:18;;:::i;:::-;14048:2;14041:22;14087:23;;14072:39;;-1:-1:-1;14079:6:137;13697:445;-1:-1:-1;13697:445:137:o;14380:196::-;14468:6;14521:3;14509:9;14500:7;14496:23;14492:33;14489:53;;;14538:1;14535;14528:12;14489:53;-1:-1:-1;14561:9:137;14380:196;-1:-1:-1;14380:196:137:o;14805:150::-;14890:13;;14912:37;14890:13;14912:37;:::i;14960:138::-;15039:13;;15061:31;15039:13;15061:31;:::i;15103:132::-;15179:13;;15201:28;15179:13;15201:28;:::i;15240:136::-;15318:13;;15340:30;15318:13;15340:30;:::i;15381:136::-;15459:13;;15481:30;15459:13;15481:30;:::i;15522:136::-;15600:13;;15622:30;15600:13;15622:30;:::i;15663:2090::-;15760:6;15813:3;15801:9;15792:7;15788:23;15784:33;15781:53;;;15830:1;15827;15820:12;15781:53;15856:17;;:::i;:::-;15896:46;15932:9;15896:46;:::i;:::-;15889:5;15882:61;15975:49;16020:2;16009:9;16005:18;15975:49;:::i;:::-;15970:2;15963:5;15959:14;15952:73;16078:2;16067:9;16063:18;16057:25;16052:2;16045:5;16041:14;16034:49;16136:2;16125:9;16121:18;16115:25;16110:2;16103:5;16099:14;16092:49;16174:47;16216:3;16205:9;16201:19;16174:47;:::i;:::-;16168:3;16161:5;16157:15;16150:72;16276:3;16265:9;16261:19;16255:26;16249:3;16242:5;16238:15;16231:51;16315:50;16360:3;16349:9;16345:19;16315:50;:::i;:::-;16309:3;16298:15;;16291:75;16420:3;16405:19;;;16399:26;16382:15;;;16375:51;16445:3;16486:18;;;16480:25;16464:14;;;16457:49;16525:3;16566:18;;;16560:25;16544:14;;;16537:49;16605:3;16646:18;;;16640:25;16624:14;;;16617:49;16685:3;16720:48;16749:18;;;16720:48;:::i;:::-;16704:14;;;16697:72;16788:3;16823:48;16852:18;;;16823:48;:::i;:::-;16807:14;;;16800:72;16891:3;16926:48;16955:18;;;16926:48;:::i;:::-;16910:14;;;16903:72;16994:3;17029:49;17059:18;;;17029:49;:::i;:::-;17013:14;;;17006:73;17098:3;17133:49;17163:18;;;17133:49;:::i;:::-;17117:14;;;17110:73;17202:3;17243:18;;;17237:25;17221:14;;;17214:49;17283:3;17319:47;17346:19;;;17319:47;:::i;:::-;17302:15;;;17295:72;17387:3;17429:19;;;17423:26;17406:15;;;17399:51;17470:3;17512:19;;;17506:26;17489:15;;;17482:51;17553:3;17595:19;;;17589:26;17572:15;;;17565:51;17636:3;17672:50;17702:19;;;17672:50;:::i;17758:345::-;-1:-1:-1;;;;;17978:32:137;;;;17960:51;;18042:2;18027:18;;18020:34;;;;18085:2;18070:18;;18063:34;17948:2;17933:18;;17758:345::o;18361:359::-;18548:6;18543:3;18536:19;18518:3;18584:6;18578:13;18600:73;18666:6;18661:2;18656:3;18652:12;18647:2;18639:6;18635:15;18600:73;:::i;:::-;18693:16;;;;18711:2;18689:25;;18361:359;-1:-1:-1;;;18361:359:137:o;19122:247::-;19181:6;19234:2;19222:9;19213:7;19209:23;19205:32;19202:52;;;19250:1;19247;19240:12;19202:52;19289:9;19276:23;19308:31;19333:5;19308:31;:::i;19374:2665::-;19564:3;19549:19;;19577:69;19553:9;19602:32;19627:6;19602:32;:::i;:::-;19577:69;:::i;:::-;19675:37;19706:4;19698:6;19694:17;19675:37;:::i;:::-;-1:-1:-1;;;;;2106:31:137;;19769:4;19754:20;;2094:44;19721:54;19838:4;19830:6;19826:17;19813:31;19806:4;19795:9;19791:20;19784:61;19908:4;19900:6;19896:17;19883:31;19876:4;19865:9;19861:20;19854:61;19946:34;19974:4;19966:6;19962:17;19946:34;:::i;:::-;4396:13;4389:21;20036:4;20021:20;;4377:34;20105:4;20093:17;;;20080:31;20058:20;;;20051:61;20143:37;20174:4;20162:17;;20143:37;:::i;:::-;-1:-1:-1;;;;;2106:31:137;20239:4;20224:20;;2094:44;20308:4;20296:17;;;20283:31;20261:20;;;20254:61;20334:6;20389:15;;;20376:29;20356:18;;;20349:57;20425:6;20480:15;;;20467:29;20447:18;;;20440:57;20516:6;20571:15;;;20558:29;20538:18;;;20531:57;20607:6;20644:34;20662:15;;;20644:34;:::i;:::-;3004:8;2993:20;20721:18;;;2981:33;20759:6;20796:34;20814:15;;;20796:34;:::i;:::-;2225:10;2214:22;20873:18;;;2202:35;20911:6;20948:34;20966:15;;;20948:34;:::i;:::-;6000:12;5989:24;21025:18;;;5977:37;21063:6;21100:35;21119:15;;;21100:35;:::i;:::-;-1:-1:-1;;;;;2106:31:137;21179:18;;;2094:44;21217:6;21254:35;21273:15;;;21254:35;:::i;:::-;-1:-1:-1;;;;;2106:31:137;21333:18;;;2094:44;21371:6;21426:15;;;21413:29;21393:18;;;21386:57;21463:6;21500:33;21516:16;;;21500:33;:::i;:::-;4396:13;4389:21;21574:19;;;4377:34;21614:6;21670:16;;;21657:30;21636:19;;;21629:59;21708:6;21764:16;;;21751:30;21730:19;;;21723:59;21802:6;21858:16;;;21845:30;21824:19;;;21817:59;21896:6;21933:36;21952:16;;;21933:36;:::i;:::-;-1:-1:-1;;;;;2106:31:137;;22013:19;;;2094:44;21978:55;2040:104;22632:245;22699:6;22752:2;22740:9;22731:7;22727:23;22723:32;22720:52;;;22768:1;22765;22758:12;22720:52;22800:9;22794:16;22819:28;22841:5;22819:28;:::i;23965:286::-;24070:6;24123:2;24111:9;24102:7;24098:23;24094:32;24091:52;;;24139:1;24136;24129:12;24091:52;24171:9;24165:16;24190:31;24215:5;24190:31;:::i;24535:184::-;24605:6;24658:2;24646:9;24637:7;24633:23;24629:32;24626:52;;;24674:1;24671;24664:12;24626:52;-1:-1:-1;24697:16:137;;24535:184;-1:-1:-1;24535:184:137:o;24977:127::-;25038:10;25033:3;25029:20;25026:1;25019:31;25069:4;25066:1;25059:15;25093:4;25090:1;25083:15;25109:128;25176:9;;;25197:11;;;25194:37;;;25211:18;;:::i;25538:288::-;25713:6;25702:9;25695:25;25756:2;25751;25740:9;25736:18;25729:30;25676:4;25776:44;25816:2;25805:9;25801:18;25793:6;25776:44;:::i;:::-;25768:52;25538:288;-1:-1:-1;;;;25538:288:137:o;25831:287::-;25960:3;25998:6;25992:13;26014:66;26073:6;26068:3;26061:4;26053:6;26049:17;26014:66;:::i;:::-;26096:16;;;;;25831:287;-1:-1:-1;;25831:287:137:o;26123:125::-;26188:9;;;26209:10;;;26206:36;;;26222:18;;:::i;26253:127::-;26314:10;26309:3;26305:20;26302:1;26295:31;26345:4;26342:1;26335:15;26369:4;26366:1;26359:15;26385:135;26424:3;26445:17;;;26442:43;;26465:18;;:::i;:::-;-1:-1:-1;26512:1:137;26501:13;;26385:135::o","linkReferences":{},"immutableReferences":{"67277":[{"start":434,"length":32},{"start":2359,"length":32}],"67279":[{"start":765,"length":32},{"start":1968,"length":32}],"67282":[{"start":487,"length":32},{"start":2659,"length":32}],"67285":[{"start":707,"length":32},{"start":1853,"length":32},{"start":3438,"length":32},{"start":3768,"length":32}],"67288":[{"start":610,"length":32},{"start":4132,"length":32}],"67291":[{"start":550,"length":32},{"start":3989,"length":32}]}},"methodIdentifiers":{"DOMAIN_SEPARATOR()":"3644e515","MULTIPROPOSAL_DOMAIN_SEPARATOR()":"abe93878","MULTIPROPOSAL_TYPEHASH()":"d06a0d82","PROPOSAL_TYPEHASH()":"853b94a0","VERSION()":"ffa1ad74","acceptProposal(address,uint256,bytes,bytes32[],bytes)":"01e83272","config()":"79502c55","decodeProposalData(bytes)":"2d5d17fc","encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":"335376cb","getMultiproposalHash((bytes32))":"829d3770","getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":"c8d44eb2","hub()":"365a86fc","makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":"a1a20ef2","proposalsMade(bytes32)":"1da4c275","revokeNonce(uint256,uint256)":"579bfc30","revokedNonce()":"9788ad55","utilizedCredit()":"4379dbad"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_hub\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_revokedNonce\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_config\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_utilizedCredit\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"AcceptorIsProposer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"AddressMissingHubTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"CallerIsNotStatedProposer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowed\",\"type\":\"address\"}],\"name\":\"CallerNotAllowedAcceptor\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"name\":\"CallerNotLoanContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"defaultDate\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"current\",\"type\":\"uint32\"}],\"name\":\"DefaultDateInPast\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"Expired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"current\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"proposed\",\"type\":\"bytes32\"}],\"name\":\"InvalidCollateralStateFingerprint\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"}],\"name\":\"InvalidRefinancingLoanId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"digest\",\"type\":\"bytes32\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MissingStateFingerprintComputer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceNotUsable\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"ProposalMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTIPROPOSAL_DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTIPROPOSAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROPOSAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"proposalData\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"proposalInclusionProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"acceptProposal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"lender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"duration\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"credit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"bytes32\",\"name\":\"lenderSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"borrowerSpecHash\",\"type\":\"bytes32\"}],\"internalType\":\"struct PWNSimpleLoan.Terms\",\"name\":\"loanTerms\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"internalType\":\"contract PWNConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"proposalData\",\"type\":\"bytes\"}],\"name\":\"decodeProposalData\",\"outputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"encodeProposalData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"multiproposalMerkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"struct PWNSimpleLoanProposal.Multiproposal\",\"name\":\"multiproposal\",\"type\":\"tuple\"}],\"name\":\"getMultiproposalHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"getProposalHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hub\",\"outputs\":[{\"internalType\":\"contract PWNHub\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"makeProposal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"proposalsMade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"revokeNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"revokedNonce\",\"outputs\":[{\"internalType\":\"contract PWNRevokedNonce\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"utilizedCredit\",\"outputs\":[{\"internalType\":\"contract PWNUtilizedCredit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"InvalidSignature(address,bytes32)\":[{\"details\":\"Thrown when signature is invalid.\"}],\"InvalidSignatureLength(uint256)\":[{\"details\":\"Thrown when signature length is not 64 nor 65 bytes.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"details\":\"Maybe nonce is revoked or not in the current nonce space.\"}]},\"kind\":\"dev\",\"methods\":{\"acceptProposal(address,uint256,bytes,bytes32[],bytes)\":{\"details\":\"Function can be called only by a loan contract with appropriate PWN Hub tag.\",\"params\":{\"acceptor\":\"Address of a proposal acceptor.\",\"proposalData\":\"Encoded proposal data with signature.\",\"proposalInclusionProof\":\"Multiproposal inclusion proof. Empty if single proposal.\",\"refinancingLoanId\":\"Id of a loan to be refinanced. 0 if creating a new loan.\"},\"returns\":{\"loanTerms\":\"Loan terms.\",\"proposalHash\":\"Proposal hash.\"}},\"decodeProposalData(bytes)\":{\"params\":{\"proposalData\":\"Encoded proposal data.\"},\"returns\":{\"_0\":\"Decoded proposal struct.\"}},\"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"params\":{\"proposal\":\"Proposal struct to be encoded.\"},\"returns\":{\"_0\":\"Encoded proposal data.\"}},\"getMultiproposalHash((bytes32))\":{\"params\":{\"multiproposal\":\"Multiproposal struct.\"},\"returns\":{\"_0\":\"Multiproposal hash.\"}},\"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"params\":{\"proposal\":\"Proposal struct to be hashed.\"},\"returns\":{\"_0\":\"Proposal struct hash.\"}},\"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"details\":\"Function will mark a proposal hash as proposed.\",\"params\":{\"proposal\":\"Proposal struct containing all needed proposal data.\"},\"returns\":{\"proposalHash\":\"Proposal hash.\"}},\"revokeNonce(uint256,uint256)\":{\"params\":{\"nonce\":\"Proposal nonce to be revoked.\",\"nonceSpace\":\"Nonce space of a proposal nonce to be revoked.\"}}},\"stateVariables\":{\"PROPOSAL_TYPEHASH\":{\"details\":\"EIP-712 simple proposal struct type hash.\"}},\"title\":\"PWN Simple Loan Simple Proposal\",\"version\":1},\"userdoc\":{\"errors\":{\"AcceptorIsProposer(address)\":[{\"notice\":\"Thrown when proposal acceptor and proposer are the same.\"}],\"AddressMissingHubTag(address,bytes32)\":[{\"notice\":\"Thrown when an address is missing a PWN Hub tag.\"}],\"CallerIsNotStatedProposer(address)\":[{\"notice\":\"Thrown when a caller is not a stated proposer.\"}],\"CallerNotAllowedAcceptor(address,address)\":[{\"notice\":\"Thrown when caller is not allowed to accept a proposal.\"}],\"CallerNotLoanContract(address,address)\":[{\"notice\":\"Thrown when a caller is missing a required hub tag.\"}],\"DefaultDateInPast(uint32,uint32)\":[{\"notice\":\"Thrown when a default date is in the past.\"}],\"Expired(uint256,uint256)\":[{\"notice\":\"Thrown when a proposal is expired.\"}],\"InvalidCollateralStateFingerprint(bytes32,bytes32)\":[{\"notice\":\"Thrown when a proposed collateral state fingerprint doesn't match the current state.\"}],\"InvalidRefinancingLoanId(uint256)\":[{\"notice\":\"Thrown when provided refinance loan id cannot be used.\"}],\"MissingStateFingerprintComputer()\":[{\"notice\":\"Thrown when a state fingerprint computer is not registered.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"notice\":\"Thrown when nonce is currently not usable.\"}]},\"events\":{\"ProposalMade(bytes32,address,(uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Emitted when a proposal is made via an on-chain transaction.\"}},\"kind\":\"user\",\"methods\":{\"acceptProposal(address,uint256,bytes,bytes32[],bytes)\":{\"notice\":\"Accept a proposal and create new loan terms.\"},\"decodeProposalData(bytes)\":{\"notice\":\"Decode proposal data.\"},\"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Encode proposal data.\"},\"getMultiproposalHash((bytes32))\":{\"notice\":\"Get a multiproposal hash according to EIP-712.\"},\"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Get an proposal hash according to EIP-712\"},\"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Make an on-chain proposal.\"},\"revokeNonce(uint256,uint256)\":{\"notice\":\"Helper function for revoking a proposal nonce on behalf of a caller.\"}},\"notice\":\"Contract for creating and accepting simple loan proposals.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol\":\"PWNSimpleLoanSimpleProposal\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/MultiToken/src/MultiToken.sol\":{\"keccak256\":\"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18\",\"dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh\"]},\"lib/MultiToken/src/interfaces/ICryptoKitties.sol\":{\"keccak256\":\"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa\",\"dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze\"]},\"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol\":{\"keccak256\":\"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1\",\"dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\":{\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16\",\"dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c\",\"dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e\",\"dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b\",\"dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95\",\"dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol\":{\"keccak256\":\"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b\",\"dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45\",\"dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol\":{\"keccak256\":\"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8\",\"dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6\"]},\"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol\":{\"keccak256\":\"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf\",\"dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec\",\"dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005\",\"dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4\",\"dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol\":{\"keccak256\":\"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04\",\"dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd\",\"dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278\",\"dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"src/PWNErrors.sol\":{\"keccak256\":\"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f\",\"dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc\"]},\"src/config/PWNConfig.sol\":{\"keccak256\":\"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7\",\"dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]},\"src/hub/PWNHubTags.sol\":{\"keccak256\":\"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8\",\"dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ\"]},\"src/interfaces/IERC5646.sol\":{\"keccak256\":\"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180\",\"dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki\"]},\"src/interfaces/IPWNLoanMetadataProvider.sol\":{\"keccak256\":\"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6\",\"dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK\"]},\"src/interfaces/IPoolAdapter.sol\":{\"keccak256\":\"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b\",\"dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T\"]},\"src/interfaces/IStateFingerpringComputer.sol\":{\"keccak256\":\"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c\",\"dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct\"]},\"src/loan/lib/PWNFeeCalculator.sol\":{\"keccak256\":\"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5\",\"dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq\"]},\"src/loan/lib/PWNSignatureChecker.sol\":{\"keccak256\":\"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1\",\"dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM\"]},\"src/loan/terms/simple/loan/PWNSimpleLoan.sol\":{\"keccak256\":\"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129\",\"dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP\"]},\"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol\":{\"keccak256\":\"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13\",\"dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP\"]},\"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol\":{\"keccak256\":\"0xbd5115ed81ecc5987dd6d21c32185269579eb2dc920572b5b725b511d6e6047c\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4bdf73983e3c1dc63d99d4aea19ebc22c533071980c9cf2741e64fea73cbea78\",\"dweb:/ipfs/QmPBiKj9qaQt4Fwbj9hG1qmh6hsMLCpXHNkRTvc5yutp3N\"]},\"src/loan/token/PWNLOAN.sol\":{\"keccak256\":\"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219\",\"dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo\"]},\"src/loan/vault/PWNVault.sol\":{\"keccak256\":\"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b\",\"dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq\"]},\"src/nonce/PWNRevokedNonce.sol\":{\"keccak256\":\"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f\",\"dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS\"]},\"src/utilized-credit/PWNUtilizedCredit.sol\":{\"keccak256\":\"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441\",\"dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"address","name":"_revokedNonce","type":"address"},{"internalType":"address","name":"_config","type":"address"},{"internalType":"address","name":"_utilizedCredit","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"type":"error","name":"AcceptorIsProposer"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"}],"type":"error","name":"AddressMissingHubTag"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"type":"error","name":"CallerIsNotStatedProposer"},{"inputs":[{"internalType":"address","name":"current","type":"address"},{"internalType":"address","name":"allowed","type":"address"}],"type":"error","name":"CallerNotAllowedAcceptor"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"loanContract","type":"address"}],"type":"error","name":"CallerNotLoanContract"},{"inputs":[{"internalType":"uint32","name":"defaultDate","type":"uint32"},{"internalType":"uint32","name":"current","type":"uint32"}],"type":"error","name":"DefaultDateInPast"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"type":"error","name":"Expired"},{"inputs":[{"internalType":"bytes32","name":"current","type":"bytes32"},{"internalType":"bytes32","name":"proposed","type":"bytes32"}],"type":"error","name":"InvalidCollateralStateFingerprint"},{"inputs":[{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"}],"type":"error","name":"InvalidRefinancingLoanId"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"digest","type":"bytes32"}],"type":"error","name":"InvalidSignature"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"type":"error","name":"InvalidSignatureLength"},{"inputs":[],"type":"error","name":"MissingStateFingerprintComputer"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"type":"error","name":"NonceNotUsable"},{"inputs":[{"internalType":"bytes32","name":"proposalHash","type":"bytes32","indexed":true},{"internalType":"address","name":"proposer","type":"address","indexed":true},{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}],"indexed":false}],"type":"event","name":"ProposalMade","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MULTIPROPOSAL_DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MULTIPROPOSAL_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"PROPOSAL_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"address","name":"acceptor","type":"address"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"bytes","name":"proposalData","type":"bytes"},{"internalType":"bytes32[]","name":"proposalInclusionProof","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"acceptProposal","outputs":[{"internalType":"bytes32","name":"proposalHash","type":"bytes32"},{"internalType":"struct PWNSimpleLoan.Terms","name":"loanTerms","type":"tuple","components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint32","name":"duration","type":"uint32"},{"internalType":"struct MultiToken.Asset","name":"collateral","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"struct MultiToken.Asset","name":"credit","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"bytes32","name":"lenderSpecHash","type":"bytes32"},{"internalType":"bytes32","name":"borrowerSpecHash","type":"bytes32"}]}]},{"inputs":[],"stateMutability":"view","type":"function","name":"config","outputs":[{"internalType":"contract PWNConfig","name":"","type":"address"}]},{"inputs":[{"internalType":"bytes","name":"proposalData","type":"bytes"}],"stateMutability":"pure","type":"function","name":"decodeProposalData","outputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}]},{"inputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}],"stateMutability":"pure","type":"function","name":"encodeProposalData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}]},{"inputs":[{"internalType":"struct PWNSimpleLoanProposal.Multiproposal","name":"multiproposal","type":"tuple","components":[{"internalType":"bytes32","name":"multiproposalMerkleRoot","type":"bytes32"}]}],"stateMutability":"view","type":"function","name":"getMultiproposalHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}],"stateMutability":"view","type":"function","name":"getProposalHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"hub","outputs":[{"internalType":"contract PWNHub","name":"","type":"address"}]},{"inputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}],"stateMutability":"nonpayable","type":"function","name":"makeProposal","outputs":[{"internalType":"bytes32","name":"proposalHash","type":"bytes32"}]},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","name":"proposalsMade","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"revokeNonce"},{"inputs":[],"stateMutability":"view","type":"function","name":"revokedNonce","outputs":[{"internalType":"contract PWNRevokedNonce","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"utilizedCredit","outputs":[{"internalType":"contract PWNUtilizedCredit","name":"","type":"address"}]}],"devdoc":{"kind":"dev","methods":{"acceptProposal(address,uint256,bytes,bytes32[],bytes)":{"details":"Function can be called only by a loan contract with appropriate PWN Hub tag.","params":{"acceptor":"Address of a proposal acceptor.","proposalData":"Encoded proposal data with signature.","proposalInclusionProof":"Multiproposal inclusion proof. Empty if single proposal.","refinancingLoanId":"Id of a loan to be refinanced. 0 if creating a new loan."},"returns":{"loanTerms":"Loan terms.","proposalHash":"Proposal hash."}},"decodeProposalData(bytes)":{"params":{"proposalData":"Encoded proposal data."},"returns":{"_0":"Decoded proposal struct."}},"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"params":{"proposal":"Proposal struct to be encoded."},"returns":{"_0":"Encoded proposal data."}},"getMultiproposalHash((bytes32))":{"params":{"multiproposal":"Multiproposal struct."},"returns":{"_0":"Multiproposal hash."}},"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"params":{"proposal":"Proposal struct to be hashed."},"returns":{"_0":"Proposal struct hash."}},"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"details":"Function will mark a proposal hash as proposed.","params":{"proposal":"Proposal struct containing all needed proposal data."},"returns":{"proposalHash":"Proposal hash."}},"revokeNonce(uint256,uint256)":{"params":{"nonce":"Proposal nonce to be revoked.","nonceSpace":"Nonce space of a proposal nonce to be revoked."}}},"version":1},"userdoc":{"kind":"user","methods":{"acceptProposal(address,uint256,bytes,bytes32[],bytes)":{"notice":"Accept a proposal and create new loan terms."},"decodeProposalData(bytes)":{"notice":"Decode proposal data."},"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"notice":"Encode proposal data."},"getMultiproposalHash((bytes32))":{"notice":"Get a multiproposal hash according to EIP-712."},"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"notice":"Get an proposal hash according to EIP-712"},"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"notice":"Make an on-chain proposal."},"revokeNonce(uint256,uint256)":{"notice":"Helper function for revoking a proposal nonce on behalf of a caller."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol":"PWNSimpleLoanSimpleProposal"},"evmVersion":"london","libraries":{}},"sources":{"lib/MultiToken/src/MultiToken.sol":{"keccak256":"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da","urls":["bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18","dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh"],"license":"MIT"},"lib/MultiToken/src/interfaces/ICryptoKitties.sol":{"keccak256":"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706","urls":["bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa","dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze"],"license":"MIT"},"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol":{"keccak256":"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a","urls":["bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1","dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol":{"keccak256":"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510","urls":["bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16","dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"keccak256":"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e","urls":["bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c","dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794","urls":["bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e","dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"keccak256":"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422","urls":["bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b","dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef","urls":["bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95","dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol":{"keccak256":"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2","urls":["bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b","dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45","urls":["bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45","dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol":{"keccak256":"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c","urls":["bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8","dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol":{"keccak256":"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582","urls":["bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf","dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol":{"keccak256":"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b","urls":["bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec","dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol":{"keccak256":"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac","urls":["bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04","dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol":{"keccak256":"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5","urls":["bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd","dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad","urls":["bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278","dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"src/PWNErrors.sol":{"keccak256":"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24","urls":["bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f","dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc"],"license":"GPL-3.0-only"},"src/config/PWNConfig.sol":{"keccak256":"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f","urls":["bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7","dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz"],"license":"GPL-3.0-only"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"},"src/hub/PWNHubTags.sol":{"keccak256":"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a","urls":["bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8","dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ"],"license":"GPL-3.0-only"},"src/interfaces/IERC5646.sol":{"keccak256":"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e","urls":["bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180","dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki"],"license":"GPL-3.0-only"},"src/interfaces/IPWNLoanMetadataProvider.sol":{"keccak256":"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8","urls":["bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6","dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK"],"license":"GPL-3.0-only"},"src/interfaces/IPoolAdapter.sol":{"keccak256":"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89","urls":["bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b","dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T"],"license":"GPL-3.0-only"},"src/interfaces/IStateFingerpringComputer.sol":{"keccak256":"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2","urls":["bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c","dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct"],"license":"GPL-3.0-only"},"src/loan/lib/PWNFeeCalculator.sol":{"keccak256":"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf","urls":["bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5","dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq"],"license":"GPL-3.0-only"},"src/loan/lib/PWNSignatureChecker.sol":{"keccak256":"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd","urls":["bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1","dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM"],"license":"GPL-3.0-only"},"src/loan/terms/simple/loan/PWNSimpleLoan.sol":{"keccak256":"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80","urls":["bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129","dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP"],"license":"GPL-3.0-only"},"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol":{"keccak256":"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96","urls":["bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13","dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP"],"license":"GPL-3.0-only"},"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol":{"keccak256":"0xbd5115ed81ecc5987dd6d21c32185269579eb2dc920572b5b725b511d6e6047c","urls":["bzz-raw://4bdf73983e3c1dc63d99d4aea19ebc22c533071980c9cf2741e64fea73cbea78","dweb:/ipfs/QmPBiKj9qaQt4Fwbj9hG1qmh6hsMLCpXHNkRTvc5yutp3N"],"license":"GPL-3.0-only"},"src/loan/token/PWNLOAN.sol":{"keccak256":"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb","urls":["bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219","dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo"],"license":"GPL-3.0-only"},"src/loan/vault/PWNVault.sol":{"keccak256":"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c","urls":["bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b","dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq"],"license":"GPL-3.0-only"},"src/nonce/PWNRevokedNonce.sol":{"keccak256":"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e","urls":["bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f","dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS"],"license":"GPL-3.0-only"},"src/utilized-credit/PWNUtilizedCredit.sol":{"keccak256":"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3","urls":["bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441","dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC"],"license":"GPL-3.0-only"}},"version":1},"id":99} \ No newline at end of file diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json new file mode 100644 index 00000000..be6bc599 --- /dev/null +++ b/packages/subgraph/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pwndao/subgraph", + "version": "0.0.1-beta.20", + "type": "module", + "license": "UNLICENSED", + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } + }, + "scripts": { + "codegen": "nx exec -- graph codegen", + "build": "nx exec -- graph build", + "deploy": "nx exec -- graph deploy --node https://api.studio.thegraph.com/deploy/ pwn-test-proposals", + "create-local": "nx exec -- graph create --node http://localhost:8020/ pwn-test-proposals", + "remove-local": "nx exec -- graph remove --node http://localhost:8020/ pwn-test-proposals", + "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals" + }, + "dependencies": { + "@graphprotocol/graph-cli": "0.97.0", + "@graphprotocol/graph-ts": "0.37.0" + }, + "files": ["dist", "!**/*.tsbuildinfo"] +} diff --git a/packages/subgraph/project.json b/packages/subgraph/project.json new file mode 100644 index 00000000..6fbecf25 --- /dev/null +++ b/packages/subgraph/project.json @@ -0,0 +1,11 @@ +{ + "name": "@pwndao/subgraph", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/subgraph/src", + "projectType": "library", + "tags": [ + "subgraph" + ], + "targets": { + } +} diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql new file mode 100644 index 00000000..2d5ddadd --- /dev/null +++ b/packages/subgraph/schema.graphql @@ -0,0 +1,97 @@ +# Define the structure of your queryable data + +type Account @entity(immutable: true) { + id: Bytes! # Ethereum address + proposalsAsBorrower: [Proposal!]! @derivedFrom(field: "borrower") + proposalsAsLender: [Proposal!]! @derivedFrom(field: "lender") + loansAsBorrower: [Loan!]! @derivedFrom(field: "borrower") + loansAsLender: [Loan!]! @derivedFrom(field: "lender") + erc20Balances: [ERC20Balance!]! @derivedFrom(field: "account") + nftBalances: [NFTBalance!]! @derivedFrom(field: "owner") +} + +type Proposal @entity(immutable: true) { + id: ID! # Combination of chainId and proposalId from contract + proposalId: BigInt! # Proposal ID from contract event + chainId: BigInt! # Chain ID where proposal exists + contractAddress: Bytes! # Address of the specific proposal contract (e.g., SimpleLoanSimpleProposal) + borrower: Account! # Borrower address + lender: Account # Lender address (null until accepted) + + collateralType: String! # ERC20, ERC721, ERC1155 + collateralAddress: Bytes! + collateralTokenId: BigInt # Null for ERC20 + collateralAmount: BigDecimal # Amount for ERC20 + + loanAmount: BigDecimal! + loanCurrency: Bytes! # Address of the loan currency (ERC20 token) + interestRate: BigDecimal # Or other interest/fee model details + duration: BigInt! # Loan duration in seconds + + status: String! # PENDING, ACCEPTED, REPAID, LIQUIDATED, CANCELED + metadataURI: String # IPFS CID for richer proposal metadata + + createdAtTimestamp: BigInt! + createdAtBlockNumber: BigInt! + transactionHash: Bytes! + + loan: Loan # Link to the resulting loan if accepted +} + +type Loan @entity(immutable: false) { + id: ID! # Combination of chainId and loanId from contract + loanId: BigInt! # Loan ID from contract event + chainId: BigInt! + contractAddress: Bytes! # Address of the specific loan contract (e.g., SimpleLoan) + proposal: Proposal! # Link back to the proposal + + borrower: Account! + lender: Account! + + startDate: BigInt! + dueDate: BigInt! + repaymentAmount: BigDecimal! # Total amount to repay (principal + interest/fees) + + status: String! # ACTIVE, REPAID, LIQUIDATED, DEFAULTED + + repaidAmount: BigDecimal # Amount repaid so far + repaidTimestamp: BigInt + liquidatedTimestamp: BigInt + + # Consider adding fields related to collateral state during the loan +} + +# --- Supporting Entities --- + +type ERC20Balance @entity(immutable: true) { + id: ID! # Combination of account address and token address + account: Account! + tokenAddress: Bytes! + amount: BigDecimal! + lastUpdatedBlock: BigInt! +} + +type NFTBalance @entity(immutable: true) { + id: ID! # Combination of owner address, contract address, and token ID + owner: Account! + contractAddress: Bytes! + tokenId: BigInt! + tokenURI: String # Fetched from contract + metadata: NFTMetadata # Link to potentially fetched metadata + lastUpdatedBlock: BigInt! +} + +type NFTMetadata @entity(immutable: true) { + id: ID! # Usually the tokenURI or CID + name: String + description: String + image: String + attributes: [NFTAttribute!] +} + +type NFTAttribute @entity(immutable: true) { + id: ID! + metadata: NFTMetadata! + trait_type: String! + value: String! +} \ No newline at end of file diff --git a/packages/subgraph/src/contract.ts b/packages/subgraph/src/contract.ts new file mode 100644 index 00000000..e407fd87 --- /dev/null +++ b/packages/subgraph/src/contract.ts @@ -0,0 +1,37 @@ +import type { + Account, + ERC20Balance, + Loan, + NFTAttribute, + NFTBalance, + NFTMetadata, + Proposal, +} from "../generated/subgraph-QmXpWoxzBQ3dvDK3WTVAyMuEtDvm4UgqLWo7kFS4M6WXnh"; + +export function handleAccount(entity: Account): void { + // Empty handler for Account +} + +export function handleProposal(entity: Proposal): void { + // Empty handler for Proposal +} + +export function handleLoan(entity: Loan): void { + // Empty handler for Loan +} + +export function handleERC20Balance(entity: ERC20Balance): void { + // Empty handler for ERC20Balance +} + +export function handleNFTBalance(entity: NFTBalance): void { + // Empty handler for NFTBalance +} + +export function handleNFTMetadata(entity: NFTMetadata): void { + // Empty handler for NFTMetadata +} + +export function handleNFTAttribute(entity: NFTAttribute): void { + // Empty handler for NFTAttribute +} diff --git a/packages/subgraph/src/loan-mapping.ts b/packages/subgraph/src/loan-mapping.ts new file mode 100644 index 00000000..e936e52f --- /dev/null +++ b/packages/subgraph/src/loan-mapping.ts @@ -0,0 +1,84 @@ +// Placeholder for SimpleLoan contract event handlers +import { BigDecimal, BigInt as BigIntType, } from "@graphprotocol/graph-ts"; +import { Address } from "@graphprotocol/graph-ts"; +import { LOANClaimed, LOANCreated, LOANPaidBack, } from "../generated/PWN_SimpleLoan/SimpleLoan"; // Path to generated code +import { Account, Loan, Proposal } from "../generated/schema"; + +// Helper to get or create an Account entity +function getOrCreateAccount(address: Address): Account { + let account = Account.load(address); + if (account == null) { + account = new Account(address); + account.save(); + } + return account; +} + +function findProposalById(proposalId: BigIntType): Proposal { + let proposal = Proposal.load(proposalId.toString()); + if (proposal == null) { + proposal = new Proposal(proposalId.toString()); + proposal.save(); + } + return proposal; +} + +export function handleLOANCreated(event: LOANCreated): void { + // TODO: Implement mapping logic based on LOANCreated event parameters + // Need to parse the complex nested tuple for proposal details + + const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; + const loan = new Loan(loanEntityId); + loan.loanId = event.params.loanId; + loan.chainId = BigIntType.fromI32(1); // TODO: Hardcoded Mainnet + loan.contractAddress = event.address; + + // Example of accessing nested data (needs verification based on ABI) + const proposalData = event.params.terms; + loan.borrower = getOrCreateAccount(proposalData.borrower).id; + loan.lender = getOrCreateAccount(proposalData.lender).id; // Lender should be set here + loan.proposal = event.params.proposalHash.toHex(); // Need a way to find the original proposal + + loan.startDate = event.block.timestamp; + loan.dueDate = event.block.timestamp.plus(proposalData.duration); // Calculate due date as start date + duration + loan.repaymentAmount = BigDecimal.fromString( + proposalData.accruingInterestAPR.toString(), + ).times(BigDecimal.fromString(proposalData.credit.amount.toString())); // Need to verify param names + + loan.status = "ACTIVE"; + loan.save(); + + // TODO: Update the linked Proposal entity status +} + +export function handleLOANPaidBack(event: LOANPaidBack): void { + const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; + const loan = Loan.load(loanEntityId); + if (!loan) return; + + loan.status = "REPAID"; + loan.repaidTimestamp = event.block.timestamp; + // loan.repaidAmount = ??? // Need event param or contract read + loan.save(); + + // TODO: Update the linked Proposal entity status +} + +export function handleLOANClaimed(event: LOANClaimed): void { + const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; + const loan = Loan.load(loanEntityId); + if (!loan) return; + + // Logic to determine if this is a liquidation or regular claim + // Could check event.block.timestamp against loan.dueDate + // Could check event.params.liquidated flag + if (event.params.defaulted) { + loan.status = "DEFAULTED"; + loan.liquidatedTimestamp = event.block.timestamp; + } else { + // Handle regular claim if necessary (maybe update status?) + } + loan.save(); + + // TODO: Update the linked Proposal entity status accordingly +} diff --git a/packages/subgraph/src/proposal-mapping.ts b/packages/subgraph/src/proposal-mapping.ts new file mode 100644 index 00000000..91dc2eaa --- /dev/null +++ b/packages/subgraph/src/proposal-mapping.ts @@ -0,0 +1,37 @@ +// Placeholder for SimpleLoanSimpleProposal contract event handlers +import { type Address, BigInt as BigIntType } from "@graphprotocol/graph-ts"; +import type { ProposalMade } from "../generated/PWN_SimpleLoanSimpleProposal/SimpleLoanSimpleProposal"; +import { Account, Proposal } from "../generated/schema"; + +// Helper to get or create an Account entity +function getOrCreateAccount(address: Address): Account { + let account = Account.load(address); + if (account == null) { + account = new Account(address); + account.save(); + } + return account; +} + +export function handleProposalMade(event: ProposalMade): void { + const proposalEntityId = event.params.proposalHash.toHex(); + const proposal = new Proposal(proposalEntityId); + + proposal.chainId = BigIntType.fromI32(1); // TODO: Hardcoded Mainnet + proposal.contractAddress = event.address; + proposal.borrower = getOrCreateAccount(event.params.proposer).id; + + proposal.collateralType = + proposal.collateralType === "0" + ? "ERC20" + : proposal.collateralType === "1" + ? "ERC721" + : "ERC1155"; + + proposal.status = "PENDING"; + proposal.createdAtTimestamp = event.block.timestamp; + proposal.createdAtBlockNumber = event.block.number; + proposal.transactionHash = event.transaction.hash; + + proposal.save(); +} diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml new file mode 100644 index 00000000..c3dbb864 --- /dev/null +++ b/packages/subgraph/subgraph.yaml @@ -0,0 +1,30 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +dataSources: + # Simple Loan Contract + - kind: ethereum/contract + name: PWN_SimpleLoan + network: base + source: + address: "0x719A69d0dc67bd3Aa7648D4694081B3c87952797" # Mainnet SimpleLoan from v1.3.json + abi: SimpleLoan + startBlock: 25032814 # TODO: Find actual deployment block + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: [ Loan, Account, Proposal ] + abis: + - name: SimpleLoan + file: ./abis/SimpleLoan.json + - name: SimpleLoanSimpleProposal # Needed for context? + file: ./abis/SimpleLoanSimpleProposal.json + eventHandlers: + - event: LOANCreated(indexed uint256,indexed bytes32,indexed address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) + handler: handleLOANCreated # Use this instead of LoanStarted + - event: LOANPaidBack(indexed uint256) + handler: handleLOANPaidBack # Use this instead of LoanRepaid + - event: LOANClaimed(indexed uint256,indexed bool) + handler: handleLOANClaimed # Potential signal for liquidation/claim + file: ./src/loan-mapping.ts diff --git a/packages/subgraph/tests/.latest.json b/packages/subgraph/tests/.latest.json new file mode 100644 index 00000000..6adc67ef --- /dev/null +++ b/packages/subgraph/tests/.latest.json @@ -0,0 +1,4 @@ +{ + "version": "0.6.0", + "timestamp": 1744902689623 +} \ No newline at end of file diff --git a/packages/subgraph/tsconfig.json b/packages/subgraph/tsconfig.json new file mode 100644 index 00000000..aecb8ec2 --- /dev/null +++ b/packages/subgraph/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@graphprotocol/graph-ts/types/tsconfig.base.json", + "include": ["src", "tests"], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/subgraph/tsconfig.lib.json b/packages/subgraph/tsconfig.lib.json new file mode 100644 index 00000000..e9e008f1 --- /dev/null +++ b/packages/subgraph/tsconfig.lib.json @@ -0,0 +1,28 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": "src", + "outDir": "dist", + "tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo", + "emitDeclarationOnly": true, + "forceConsistentCasingInFileNames": true, + "types": ["node", "vite/client"] + }, + "include": ["src/**/*.ts"], + "references": [], + "exclude": [ + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx" + ] +} diff --git a/packages/subgraph/tsconfig.spec.json b/packages/subgraph/tsconfig.spec.json new file mode 100644 index 00000000..f68d9d3b --- /dev/null +++ b/packages/subgraph/tsconfig.spec.json @@ -0,0 +1,34 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./out-tsc/vitest", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ], + "forceConsistentCasingInFileNames": true + }, + "include": [ + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/packages/v1-core/src/contracts/base-proposal-contract.ts b/packages/v1-core/src/contracts/base-proposal-contract.ts index ff358b93..88b83599 100644 --- a/packages/v1-core/src/contracts/base-proposal-contract.ts +++ b/packages/v1-core/src/contracts/base-proposal-contract.ts @@ -3,7 +3,6 @@ import { type Config, getAccount, getPublicClient, - getWalletClient, readContract, signTypedData, watchContractEvent, diff --git a/packages/v1-core/src/contracts/chain-link-proposal-contract.ts b/packages/v1-core/src/contracts/chain-link-proposal-contract.ts index 2e5c9a9e..5fb26888 100644 --- a/packages/v1-core/src/contracts/chain-link-proposal-contract.ts +++ b/packages/v1-core/src/contracts/chain-link-proposal-contract.ts @@ -1,5 +1,4 @@ import { getChainLinkProposalContractAddress } from "@pwndao/sdk-core"; -import type { Config } from "@wagmi/core"; import { getAccount } from "@wagmi/core"; import type { Hex } from "viem"; import type { Address } from "viem"; diff --git a/packages/v1-core/src/contracts/elastic-proposal-contract.ts b/packages/v1-core/src/contracts/elastic-proposal-contract.ts index c81d9325..50c7e10c 100644 --- a/packages/v1-core/src/contracts/elastic-proposal-contract.ts +++ b/packages/v1-core/src/contracts/elastic-proposal-contract.ts @@ -1,5 +1,4 @@ import { getElasticProposalContractAddress } from "@pwndao/sdk-core"; -import type { Config } from "@wagmi/core"; import { getAccount } from "@wagmi/core"; import type { Hex } from "viem"; import type { Address } from "viem"; diff --git a/packages/v1-sdk-react/package.json b/packages/v1-sdk-react/package.json index 308c59d6..429b23a2 100644 --- a/packages/v1-sdk-react/package.json +++ b/packages/v1-sdk-react/package.json @@ -41,7 +41,8 @@ "@pwndao/sdk-core": "0.0.1-beta.20", "@pwndao/v1-core": "0.0.1-beta.20", "vitest": "^1.3.1", - "wagmi": "^2.14.13" + "wagmi": "^2.14.13", + "ts-invariant": "^0.10.3" }, "peerDependencies": { "@tanstack/react-query": "^5.67.3", @@ -53,7 +54,7 @@ "@testing-library/react": "^14.2.1", "jsdom": "^24.0.0", "prettier": "^2.6.2", - "react": "19.0.0", + "react": "^19.0.0", "vitest": "^1.3.1" } } From 53d783c1ec6ad9e1d55e6a8f12ef503fc4405a35 Mon Sep 17 00:00:00 2001 From: Skas Merkushin Date: Tue, 27 May 2025 07:13:37 +0200 Subject: [PATCH 02/13] wip --- bun.lockb | Bin 1358680 -> 1362872 bytes .../abis/SimpleLoanSimpleProposal.json | 1 - packages/subgraph/config/mainnet.json | 5 + packages/subgraph/config/sepolia.json | 5 + packages/subgraph/package.json | 7 +- packages/subgraph/schema.graphql | 111 ++++++------------ packages/subgraph/src/loan-mapping.ts | 81 +++++++------ packages/subgraph/src/proposal-mapping.ts | 37 ------ packages/subgraph/subgraph.template.yaml | 28 +++++ packages/subgraph/subgraph.yaml | 16 ++- 10 files changed, 128 insertions(+), 163 deletions(-) delete mode 100644 packages/subgraph/abis/SimpleLoanSimpleProposal.json create mode 100644 packages/subgraph/config/mainnet.json create mode 100644 packages/subgraph/config/sepolia.json delete mode 100644 packages/subgraph/src/proposal-mapping.ts create mode 100644 packages/subgraph/subgraph.template.yaml diff --git a/bun.lockb b/bun.lockb index ad911671f8b80eb23a1785c670eade5b02cc5b75..9d0adcd465e62171d5c373bdbf725ef7759418c4 100755 GIT binary patch delta 43500 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 GF#-Ve^pK?h diff --git a/packages/subgraph/abis/SimpleLoanSimpleProposal.json b/packages/subgraph/abis/SimpleLoanSimpleProposal.json deleted file mode 100644 index 0063e9bc..00000000 --- a/packages/subgraph/abis/SimpleLoanSimpleProposal.json +++ /dev/null @@ -1 +0,0 @@ -{"abi":[{"type":"constructor","inputs":[{"name":"_hub","type":"address","internalType":"address"},{"name":"_revokedNonce","type":"address","internalType":"address"},{"name":"_config","type":"address","internalType":"address"},{"name":"_utilizedCredit","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MULTIPROPOSAL_DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MULTIPROPOSAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"PROPOSAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"VERSION","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"acceptProposal","inputs":[{"name":"acceptor","type":"address","internalType":"address"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"proposalData","type":"bytes","internalType":"bytes"},{"name":"proposalInclusionProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"proposalHash","type":"bytes32","internalType":"bytes32"},{"name":"loanTerms","type":"tuple","internalType":"struct PWNSimpleLoan.Terms","components":[{"name":"lender","type":"address","internalType":"address"},{"name":"borrower","type":"address","internalType":"address"},{"name":"duration","type":"uint32","internalType":"uint32"},{"name":"collateral","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"credit","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"lenderSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"borrowerSpecHash","type":"bytes32","internalType":"bytes32"}]}],"stateMutability":"nonpayable"},{"type":"function","name":"config","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNConfig"}],"stateMutability":"view"},{"type":"function","name":"decodeProposalData","inputs":[{"name":"proposalData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"stateMutability":"pure"},{"type":"function","name":"encodeProposalData","inputs":[{"name":"proposal","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"pure"},{"type":"function","name":"getMultiproposalHash","inputs":[{"name":"multiproposal","type":"tuple","internalType":"struct PWNSimpleLoanProposal.Multiproposal","components":[{"name":"multiproposalMerkleRoot","type":"bytes32","internalType":"bytes32"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getProposalHash","inputs":[{"name":"proposal","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"hub","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNHub"}],"stateMutability":"view"},{"type":"function","name":"makeProposal","inputs":[{"name":"proposal","type":"tuple","internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"outputs":[{"name":"proposalHash","type":"bytes32","internalType":"bytes32"}],"stateMutability":"nonpayable"},{"type":"function","name":"proposalsMade","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"revokeNonce","inputs":[{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokedNonce","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNRevokedNonce"}],"stateMutability":"view"},{"type":"function","name":"utilizedCredit","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNUtilizedCredit"}],"stateMutability":"view"},{"type":"event","name":"ProposalMade","inputs":[{"name":"proposalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"proposer","type":"address","indexed":true,"internalType":"address"},{"name":"proposal","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","components":[{"name":"collateralCategory","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"collateralAddress","type":"address","internalType":"address"},{"name":"collateralId","type":"uint256","internalType":"uint256"},{"name":"collateralAmount","type":"uint256","internalType":"uint256"},{"name":"checkCollateralStateFingerprint","type":"bool","internalType":"bool"},{"name":"collateralStateFingerprint","type":"bytes32","internalType":"bytes32"},{"name":"creditAddress","type":"address","internalType":"address"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"availableCreditLimit","type":"uint256","internalType":"uint256"},{"name":"utilizedCreditId","type":"bytes32","internalType":"bytes32"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"durationOrDate","type":"uint32","internalType":"uint32"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"allowedAcceptor","type":"address","internalType":"address"},{"name":"proposer","type":"address","internalType":"address"},{"name":"proposerSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"isOffer","type":"bool","internalType":"bool"},{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"loanContract","type":"address","internalType":"address"}]}],"anonymous":false},{"type":"error","name":"AcceptorIsProposer","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"type":"error","name":"AddressMissingHubTag","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"CallerIsNotStatedProposer","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"type":"error","name":"CallerNotAllowedAcceptor","inputs":[{"name":"current","type":"address","internalType":"address"},{"name":"allowed","type":"address","internalType":"address"}]},{"type":"error","name":"CallerNotLoanContract","inputs":[{"name":"caller","type":"address","internalType":"address"},{"name":"loanContract","type":"address","internalType":"address"}]},{"type":"error","name":"DefaultDateInPast","inputs":[{"name":"defaultDate","type":"uint32","internalType":"uint32"},{"name":"current","type":"uint32","internalType":"uint32"}]},{"type":"error","name":"Expired","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"expiration","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidCollateralStateFingerprint","inputs":[{"name":"current","type":"bytes32","internalType":"bytes32"},{"name":"proposed","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidRefinancingLoanId","inputs":[{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSignature","inputs":[{"name":"signer","type":"address","internalType":"address"},{"name":"digest","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidSignatureLength","inputs":[{"name":"length","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"MissingStateFingerprintComputer","inputs":[]},{"type":"error","name":"NonceNotUsable","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"bytecode":{"object":"0x6101406040523480156200001257600080fd5b50604051620027a4380380620027a48339810160408190526200003591620001f6565b604080518082018252601b81527f50574e53696d706c654c6f616e53696d706c6550726f706f73616c0000000000602080830191909152825180840184526003815262312e3360e81b818301526001600160a01b0380891660c05280881660e05280871661010052851661012052925187938793879387939192917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f91620000e09185910162000253565b604051602081830303815290604052805190602001208260405160200162000109919062000253565b60408051601f1981840301815282825280516020918201209083019490945281019190915260608101919091524660808201523060a082015260c00160408051808303601f1901815282825280516020918201206080527fb2178a58fb1eefb359ecfdd57bb19c0bdd0f4e6eed8547f46600e500ed111af3908301527fb63b40822cc79278afd8d1ce1a8006a4a298ec829d4d1610b69b2a4830c232709082015260600160408051601f19818403018152919052805160209091012060a052506200028498505050505050505050565b80516001600160a01b0381168114620001f157600080fd5b919050565b600080600080608085870312156200020d57600080fd5b6200021885620001d9565b93506200022860208601620001d9565b92506200023860408601620001d9565b91506200024860608601620001d9565b905092959194509250565b6000825160005b818110156200027657602081860181015185830152016200025a565b506000920191825250919050565b60805160a05160c05160e05161010051610120516124986200030c600039600081816102260152610f9501526000818161026201526110240152600081816102c30152818161073d01528181610d6e0152610eb80152600081816101e70152610a630152600081816102fd01526107b00152600081816101b2015261093701526124986000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806379502c55116100a2578063a1a20ef211610071578063a1a20ef2146102e5578063abe93878146102f8578063c8d44eb21461031f578063d06a0d8214610332578063ffa1ad741461035957600080fd5b806379502c551461025d578063829d377014610284578063853b94a0146102975780639788ad55146102be57600080fd5b80633644e515116100de5780633644e515146101ad578063365a86fc146101e25780634379dbad14610221578063579bfc301461024857600080fd5b806301e83272146101105780631da4c2751461013a5780632d5d17fc1461016d578063335376cb1461018d575b600080fd5b61012361011e3660046118e9565b61037b565b604051610131929190611a3b565b60405180910390f35b61015d610148366004611adb565b60006020819052908152604090205460ff1681565b6040519015158152602001610131565b61018061017b366004611b34565b610634565b6040516101319190611be5565b6101a061019b366004611dbe565b6106fd565b6040516101319190611f61565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b61025b610256366004611f74565b610726565b005b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d4610292366004611f96565b6107ac565b6101d47f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a5970781565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d46102f3366004611fd8565b61087c565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b6101d461032d366004611fd8565b6108fc565b6101d47f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d81565b6101a060405180604001604052806003815260200162312e3360e81b81525081565b60006103856117f5565b60006103c689898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061063492505050565b90506104117f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707826040516020016103fd9190611be5565b604051602081830303815290604052610933565b92506104fb8b8b858a8a8a8a604051806101e001604052808a602001516001600160a01b031681526020018a6040015181526020018a60800151151581526020018a60a0015181526020018a60e0015181526020018a610100015181526020018a610120015181526020018a6101a0015164ffffffffff1681526020018a6101c001516001600160a01b031681526020018a6101e001516001600160a01b031681526020018a6102200151151581526020018a610240015181526020018a610260015181526020018a610280015181526020018a6102a001516001600160a01b03168152506109c4565b604051806101200160405280826102200151610517578c61051e565b826101e001515b6001600160a01b0316815260200182610220015161054157826101e00151610543565b8c5b6001600160a01b0316815260200161055f8361018001516111d7565b63ffffffff16815260200160405180608001604052808460000151600381111561058b5761058b6119d0565b815260200184602001516001600160a01b0316815260200184604001518152602001846060015181525081526020016105cc8360c001518460e0015161123a565b8152602001826101400151815260200182610160015162ffffff1681526020018261022001516105fd576000610604565b8261020001515b815260200182610220015161061e57826102000151610621565b60005b8152509150509850989650505050505050565b604080516102c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a0820152825190916106f79184018101908401612033565b92915050565b6060816040516020016107109190611be5565b6040516020818303038152906040529050919050565b60405163f79924a960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f79924a9906107769033908690869060040161217b565b600060405180830381600087803b15801561079057600080fd5b505af11580156107a4573d6000803e3d6000fd5b505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d836040516020016108049151815260200190565b60408051601f1981840301815290829052610822929160200161219c565b6040516020818303038152906040528051906020012060405160200161085f92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b6000610887826108fc565b90506108a48161089f61020085016101e086016121c2565b611272565b6108b661020083016101e084016121c2565b6001600160a01b0316817f94918c29cf820aa7f4261a4066a6933ed25b5aa16ee856d34f6ad5517eb44d22846040516108ef91906121df565b60405180910390a3919050565b60006106f77f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707836040516020016103fd91906121df565b60007f0000000000000000000000000000000000000000000000000000000000000000838360405160200161096992919061219c565b604051602081830303815290604052805190602001206040516020016109a692919061190160f01b81526002810192909252602282015260420190565b60405160208183030381529060405280519060200120905092915050565b806101c001516001600160a01b0316336001600160a01b031614610a18576101c081015160405163a4ce7f2960e01b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6101c081015160405163680cabbd60e11b81526001600160a01b0391821660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201527f00000000000000000000000000000000000000000000000000000000000000009091169063d019577a90604401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190612367565b610b25576101c0810151604051630b92eb2560e11b81526001600160a01b0390911660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946024820152604401610a0f565b6000849003610bc55760008681526020819052604090205460ff16610bc057610b8a8161012001518785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610bc0576101208101516040516301d2d55760e31b81526001600160a01b03909116600482015260248101879052604401610a0f565b610c67565b6000610be76040518060200160405280610be089898c611469565b90526107ac565b9050610c2f8261012001518286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610c65576101208201516040516301d2d55760e31b81526001600160a01b03909116600482015260248101829052604401610a0f565b505b876001600160a01b03168161012001516001600160a01b031603610ca9576040516326ab1a1d60e11b81526001600160a01b0389166004820152602401610a0f565b86600003610ce35761016081015115610cde57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b610d2c565b8061016001518714610d2c57610160810151151580610d055750806101400151155b15610d2c57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b8060e0015164ffffffffff164210610d6c5760e081015160405163aa2fd92560e01b815242600482015264ffffffffff9091166024820152604401610a0f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f291a62c826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610dcb9392919061217b565b602060405180830381865afa158015610de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0c9190612367565b610e3e57806101200151816101800151826101a00151604051632108c30560e11b8152600401610a0f9392919061217b565b6101008101516001600160a01b031615801590610e7257508061010001516001600160a01b0316886001600160a01b031614155b15610eaa57610100810151604051636075c95560e11b81526001600160a01b03808b1660048301529091166024820152604401610a0f565b8060a00151600003610f4c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f79924a9826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610f159392919061217b565b600060405180830381600087803b158015610f2f57600080fd5b505af1158015610f43573d6000803e3d6000fd5b50505050610ff4565b61012081015160c0820151608083015160a0840151604051638f8ea94960e01b81526001600160a01b0394851660048201526024810193909352604483019190915260648201527f000000000000000000000000000000000000000000000000000000000000000090911690638f8ea94990608401600060405180830381600087803b158015610fdb57600080fd5b505af1158015610fef573d6000803e3d6000fd5b505050505b8060400151156111cd578051604051630b7e49eb60e21b81526001600160a01b03918216600482015260009182917f000000000000000000000000000000000000000000000000000000000000000090911690632df927ac90602401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612384565b90506001600160a01b0381161561112f578251602084015160405163ec2ce34560e01b81526001600160a01b0384169263ec2ce345926110e7926004016001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015611104573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112891906123a1565b9150611196565b82516111429063f511231560e01b6114b5565b1561117d578251602084015160405163f511231560e01b81526001600160a01b039092169163f5112315916110e79160040190815260200190565b60405163f3c0936360e01b815260040160405180910390fd5b818360600151146111ca576060830151604051633840fc0160e01b8152610a0f918491600401918252602082015260400190565b50505b5050505050505050565b6000633b9aca008263ffffffff16116111ee575090565b428263ffffffff16111561120c576106f74263ffffffff84166123d0565b60405163e5084aed60e01b815263ffffffff808416600483015242166024820152604401610a0f565b919050565b61124261184e565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b336001600160a01b038216146112a657604051631144200360e31b81526001600160a01b0382166004820152602401610a0f565b506000908152602081905260409020805460ff19166001179055565b60006001600160a01b0384163b156113bd57600080856001600160a01b0316631626ba7e60e01b86866040516024016112fc9291906123e3565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161133a9190612404565b600060405180830381855afa9150503d8060008114611375576040519150601f19603f3d011682016040523d82523d6000602084013e61137a565b606091505b509150915081801561138d575080516020145b80156113b457508051630b135d3f60e11b906113b290830160209081019084016123a1565b145b92505050611462565b600080600084516041036113e55750505060208201516040830151606084015160001a61143c565b845160400361141e57602085015160408601519093506001600160ff1b038116925061141660ff82901c601b612420565b91505061143c565b845160405163058676ad60e31b8152600401610a0f91815260200190565b611448868285856114d1565b6001600160a01b0316876001600160a01b03161493505050505b9392505050565b600081815b848110156114ac576114988287878481811061148c5761148c612433565b905060200201356114f9565b9150806114a481612449565b91505061146e565b50949350505050565b60006114c083611528565b80156114625750611462838361155b565b60008060006114e2878787876115e4565b915091506114ef816116a8565b5095945050505050565b6000818310611515576000828152602084905260409020611462565b6000838152602083905260409020611462565b600061153b826301ffc9a760e01b61155b565b80156106f75750611554826001600160e01b031961155b565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156115cd575060208210155b80156115d95750600081115b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561161b575060009050600361169f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561166f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116985760006001925092505061169f565b9150600090505b94509492505050565b60008160048111156116bc576116bc6119d0565b036116c45750565b60018160048111156116d8576116d86119d0565b036117255760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a0f565b6002816004811115611739576117396119d0565b036117865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a0f565b600381600481111561179a5761179a6119d0565b036117f25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a0f565b50565b6040805161012081018252600080825260208201819052918101919091526060810161181f61184e565b815260200161182c61184e565b8152600060208201819052604082018190526060820181905260809091015290565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b6001600160a01b03811681146117f257600080fd5b803561123581611880565b60008083601f8401126118b257600080fd5b50813567ffffffffffffffff8111156118ca57600080fd5b6020830191508360208285010111156118e257600080fd5b9250929050565b60008060008060008060008060a0898b03121561190557600080fd5b883561191081611880565b975060208901359650604089013567ffffffffffffffff8082111561193457600080fd5b6119408c838d016118a0565b909850965060608b013591508082111561195957600080fd5b818b0191508b601f83011261196d57600080fd5b81358181111561197c57600080fd5b8c60208260051b850101111561199157600080fd5b6020830196508095505060808b01359150808211156119af57600080fd5b506119bc8b828c016118a0565b999c989b5096995094979396929594505050565b634e487b7160e01b600052602160045260246000fd5b60048110611a0457634e487b7160e01b600052602160045260246000fd5b9052565b611a138282516119e6565b6020818101516001600160a01b03169083015260408082015190830152606090810151910152565b82815281516001600160a01b03166020820152610200810160208301516001600160a01b038116604084015250604083015163ffffffff81166060840152506060830151611a8c6080840182611a08565b506080830151610100611aa181850183611a08565b60a085015161018085015260c085015162ffffff166101a085015260e08501516101c0850152909301516101e09092019190915292915050565b600060208284031215611aed57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102c0810167ffffffffffffffff81118282101715611b2e57611b2e611af4565b60405290565b600060208284031215611b4657600080fd5b813567ffffffffffffffff80821115611b5e57600080fd5b818401915084601f830112611b7257600080fd5b813581811115611b8457611b84611af4565b604051601f8201601f19908116603f01168101908382118183101715611bac57611bac611af4565b81604052828152876020848701011115611bc557600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006102c082019050611bf98284516119e6565b6020830151611c1360208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151611c3b608084018215159052565b5060a083015160a083015260c0830151611c6060c08401826001600160a01b03169052565b5060e083810151908301526101008084015190830152610120808401519083015261014080840151908301526101608084015162ffffff16908301526101808084015163ffffffff16908301526101a08084015164ffffffffff16908301526101c0808401516001600160a01b03908116918401919091526101e0808501518216908401526102008085015190840152610220808501511515908401526102408085015190840152610260808501519084015261028080850151908401526102a08085015191821681850152905b505092915050565b600481106117f257600080fd5b803561123581611d36565b80151581146117f257600080fd5b803561123581611d4e565b62ffffff811681146117f257600080fd5b803561123581611d67565b63ffffffff811681146117f257600080fd5b803561123581611d83565b64ffffffffff811681146117f257600080fd5b803561123581611da0565b60006102c08284031215611dd157600080fd5b611dd9611b0a565b611de283611d43565b8152611df060208401611895565b60208201526040830135604082015260608301356060820152611e1560808401611d5c565b608082015260a083013560a0820152611e3060c08401611895565b60c082015260e08381013590820152610100808401359082015261012080840135908201526101408084013590820152610160611e6e818501611d78565b90820152610180611e80848201611d95565b908201526101a0611e92848201611db3565b908201526101c0611ea4848201611895565b908201526101e0611eb6848201611895565b908201526102008381013590820152610220611ed3818501611d5c565b908201526102408381013590820152610260808401359082015261028080840135908201526102a0611f06818501611895565b908201529392505050565b60005b83811015611f2c578181015183820152602001611f14565b50506000910152565b60008151808452611f4d816020860160208601611f11565b601f01601f19169290920160200192915050565b6020815260006114626020830184611f35565b60008060408385031215611f8757600080fd5b50508035926020909101359150565b600060208284031215611fa857600080fd5b6040516020810181811067ffffffffffffffff82111715611fcb57611fcb611af4565b6040529135825250919050565b60006102c08284031215611feb57600080fd5b50919050565b805161123581611d36565b805161123581611880565b805161123581611d4e565b805161123581611d67565b805161123581611d83565b805161123581611da0565b60006102c0828403121561204657600080fd5b61204e611b0a565b61205783611ff1565b815261206560208401611ffc565b6020820152604083015160408201526060830151606082015261208a60808401612007565b608082015260a083015160a08201526120a560c08401611ffc565b60c082015260e083810151908201526101008084015190820152610120808401519082015261014080840151908201526101606120e3818501612012565b908201526101806120f584820161201d565b908201526101a0612107848201612028565b908201526101c0612119848201611ffc565b908201526101e061212b848201611ffc565b908201526102008381015190820152610220612148818501612007565b908201526102408381015190820152610260808401519082015261028080840151908201526102a0611f06818501611ffc565b6001600160a01b039390931683526020830191909152604082015260600190565b828152600082516121b4816020850160208701611f11565b919091016020019392505050565b6000602082840312156121d457600080fd5b813561146281611880565b6102c081016121f6826121f185611d43565b6119e6565b61220260208401611895565b6001600160a01b038116602084015250604083013560408301526060830135606083015261223260808401611d5c565b1515608083015260a0838101359083015261224f60c08401611895565b6001600160a01b031660c083015260e08381013590830152610100808401359083015261012080840135908301526101408084013590830152610160612296818501611d78565b62ffffff16908301526101806122ad848201611d95565b63ffffffff16908301526101a06122c5848201611db3565b64ffffffffff16908301526101c06122de848201611895565b6001600160a01b0316908301526101e06122f9848201611895565b6001600160a01b031690830152610200838101359083015261022061231f818501611d5c565b1515908301526102408381013590830152610260808401359083015261028080840135908301526102a0612354818501611895565b6001600160a01b03811684830152611d2e565b60006020828403121561237957600080fd5b815161146281611d4e565b60006020828403121561239657600080fd5b815161146281611880565b6000602082840312156123b357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106f7576106f76123ba565b8281526040602082015260006123fc6040830184611f35565b949350505050565b60008251612416818460208701611f11565b9190910192915050565b808201808211156106f7576106f76123ba565b634e487b7160e01b600052603260045260246000fd5b60006001820161245b5761245b6123ba565b506001019056fea2646970667358221220d1c79fb65b29e4e9487c9bdf24e8c0288745b6e97771284c74f63ca87e7f741164736f6c63430008100033","sourceMap":"421:8910:99:-:0;;;4929:240;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4051:867:98;;;;;;;;;;;;;;;;;;;;5158:7:99;;;;;;;;;;-1:-1:-1;;;5158:7:99;;;;-1:-1:-1;;;;;4249:18:98;;;;;4277:45;;;;;4332:27;;;;;4369:51;;;;4603:22;;5080:4:99;;5086:13;;5101:7;;5110:15;;4051:867:98;;5158:7:99;4484:95:98;;4603:22;;4051:867;;4603:22;;:::i;:::-;;;;;;;;;;;;;4593:33;;;;;;4667:7;4650:25;;;;;;;;:::i;:::-;;;;-1:-1:-1;;4650:25:98;;;;;;;;;4640:36;;4650:25;4640:36;;;;4460:280;;;1343:25:137;;;;1384:18;;1377:34;;;;1427:18;;;1420:34;;;;4690:13:98;1470:18:137;;;1463:34;4725:4:98;1513:19:137;;;1506:61;1315:19;;4460:280:98;;;;;;-1:-1:-1;;4460:280:98;;;;;;4450:291;;4460:280;4450:291;;;;4431:310;;4819:38;4795:115;;;1752:25:137;4871:29:98;1793:18:137;;;1786:34;1725:18;;4795:115:98;;;-1:-1:-1;;4795:115:98;;;;;;;;;4785:126;;4795:115;4785:126;;;;4752:159;;-1:-1:-1;421:8910:99;;-1:-1:-1;;;;;;;;;421:8910:99;14:177:137;93:13;;-1:-1:-1;;;;;135:31:137;;125:42;;115:70;;181:1;178;171:12;115:70;14:177;;;:::o;196:464::-;293:6;301;309;317;370:3;358:9;349:7;345:23;341:33;338:53;;;387:1;384;377:12;338:53;410:40;440:9;410:40;:::i;:::-;400:50;;469:49;514:2;503:9;499:18;469:49;:::i;:::-;459:59;;537:49;582:2;571:9;567:18;537:49;:::i;:::-;527:59;;605:49;650:2;639:9;635:18;605:49;:::i;:::-;595:59;;196:464;;;;;;;:::o;665:414::-;796:3;834:6;828:13;859:1;869:129;883:6;880:1;877:13;869:129;;;981:4;965:14;;;961:25;;955:32;942:11;;;935:53;898:12;869:129;;;-1:-1:-1;1053:1:137;1017:16;;1042:13;;;-1:-1:-1;1017:16:137;665:414;-1:-1:-1;665:414:137:o;1578:248::-;421:8910:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b506004361061010b5760003560e01c806379502c55116100a2578063a1a20ef211610071578063a1a20ef2146102e5578063abe93878146102f8578063c8d44eb21461031f578063d06a0d8214610332578063ffa1ad741461035957600080fd5b806379502c551461025d578063829d377014610284578063853b94a0146102975780639788ad55146102be57600080fd5b80633644e515116100de5780633644e515146101ad578063365a86fc146101e25780634379dbad14610221578063579bfc301461024857600080fd5b806301e83272146101105780631da4c2751461013a5780632d5d17fc1461016d578063335376cb1461018d575b600080fd5b61012361011e3660046118e9565b61037b565b604051610131929190611a3b565b60405180910390f35b61015d610148366004611adb565b60006020819052908152604090205460ff1681565b6040519015158152602001610131565b61018061017b366004611b34565b610634565b6040516101319190611be5565b6101a061019b366004611dbe565b6106fd565b6040516101319190611f61565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610131565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b61025b610256366004611f74565b610726565b005b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d4610292366004611f96565b6107ac565b6101d47f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a5970781565b6102097f000000000000000000000000000000000000000000000000000000000000000081565b6101d46102f3366004611fd8565b61087c565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b6101d461032d366004611fd8565b6108fc565b6101d47f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d81565b6101a060405180604001604052806003815260200162312e3360e81b81525081565b60006103856117f5565b60006103c689898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061063492505050565b90506104117f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707826040516020016103fd9190611be5565b604051602081830303815290604052610933565b92506104fb8b8b858a8a8a8a604051806101e001604052808a602001516001600160a01b031681526020018a6040015181526020018a60800151151581526020018a60a0015181526020018a60e0015181526020018a610100015181526020018a610120015181526020018a6101a0015164ffffffffff1681526020018a6101c001516001600160a01b031681526020018a6101e001516001600160a01b031681526020018a6102200151151581526020018a610240015181526020018a610260015181526020018a610280015181526020018a6102a001516001600160a01b03168152506109c4565b604051806101200160405280826102200151610517578c61051e565b826101e001515b6001600160a01b0316815260200182610220015161054157826101e00151610543565b8c5b6001600160a01b0316815260200161055f8361018001516111d7565b63ffffffff16815260200160405180608001604052808460000151600381111561058b5761058b6119d0565b815260200184602001516001600160a01b0316815260200184604001518152602001846060015181525081526020016105cc8360c001518460e0015161123a565b8152602001826101400151815260200182610160015162ffffff1681526020018261022001516105fd576000610604565b8261020001515b815260200182610220015161061e57826102000151610621565b60005b8152509150509850989650505050505050565b604080516102c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a0820152825190916106f79184018101908401612033565b92915050565b6060816040516020016107109190611be5565b6040516020818303038152906040529050919050565b60405163f79924a960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f79924a9906107769033908690869060040161217b565b600060405180830381600087803b15801561079057600080fd5b505af11580156107a4573d6000803e3d6000fd5b505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f73af92d8ed4d3261ba61cd686d2f8a9cceb2563cc7c4c5355eb121316fc5358d836040516020016108049151815260200190565b60408051601f1981840301815290829052610822929160200161219c565b6040516020818303038152906040528051906020012060405160200161085f92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b6000610887826108fc565b90506108a48161089f61020085016101e086016121c2565b611272565b6108b661020083016101e084016121c2565b6001600160a01b0316817f94918c29cf820aa7f4261a4066a6933ed25b5aa16ee856d34f6ad5517eb44d22846040516108ef91906121df565b60405180910390a3919050565b60006106f77f2e066359c428f5681631554efb295dea6f4a2632b8af4164dd1849b5e6a59707836040516020016103fd91906121df565b60007f0000000000000000000000000000000000000000000000000000000000000000838360405160200161096992919061219c565b604051602081830303815290604052805190602001206040516020016109a692919061190160f01b81526002810192909252602282015260420190565b60405160208183030381529060405280519060200120905092915050565b806101c001516001600160a01b0316336001600160a01b031614610a18576101c081015160405163a4ce7f2960e01b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6101c081015160405163680cabbd60e11b81526001600160a01b0391821660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201527f00000000000000000000000000000000000000000000000000000000000000009091169063d019577a90604401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190612367565b610b25576101c0810151604051630b92eb2560e11b81526001600160a01b0390911660048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946024820152604401610a0f565b6000849003610bc55760008681526020819052604090205460ff16610bc057610b8a8161012001518785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610bc0576101208101516040516301d2d55760e31b81526001600160a01b03909116600482015260248101879052604401610a0f565b610c67565b6000610be76040518060200160405280610be089898c611469565b90526107ac565b9050610c2f8261012001518286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112c292505050565b610c65576101208201516040516301d2d55760e31b81526001600160a01b03909116600482015260248101829052604401610a0f565b505b876001600160a01b03168161012001516001600160a01b031603610ca9576040516326ab1a1d60e11b81526001600160a01b0389166004820152602401610a0f565b86600003610ce35761016081015115610cde57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b610d2c565b8061016001518714610d2c57610160810151151580610d055750806101400151155b15610d2c57806101600151604051637a4b6f9760e11b8152600401610a0f91815260200190565b8060e0015164ffffffffff164210610d6c5760e081015160405163aa2fd92560e01b815242600482015264ffffffffff9091166024820152604401610a0f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f291a62c826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610dcb9392919061217b565b602060405180830381865afa158015610de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0c9190612367565b610e3e57806101200151816101800151826101a00151604051632108c30560e11b8152600401610a0f9392919061217b565b6101008101516001600160a01b031615801590610e7257508061010001516001600160a01b0316886001600160a01b031614155b15610eaa57610100810151604051636075c95560e11b81526001600160a01b03808b1660048301529091166024820152604401610a0f565b8060a00151600003610f4c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f79924a9826101200151836101800151846101a001516040518463ffffffff1660e01b8152600401610f159392919061217b565b600060405180830381600087803b158015610f2f57600080fd5b505af1158015610f43573d6000803e3d6000fd5b50505050610ff4565b61012081015160c0820151608083015160a0840151604051638f8ea94960e01b81526001600160a01b0394851660048201526024810193909352604483019190915260648201527f000000000000000000000000000000000000000000000000000000000000000090911690638f8ea94990608401600060405180830381600087803b158015610fdb57600080fd5b505af1158015610fef573d6000803e3d6000fd5b505050505b8060400151156111cd578051604051630b7e49eb60e21b81526001600160a01b03918216600482015260009182917f000000000000000000000000000000000000000000000000000000000000000090911690632df927ac90602401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612384565b90506001600160a01b0381161561112f578251602084015160405163ec2ce34560e01b81526001600160a01b0384169263ec2ce345926110e7926004016001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015611104573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112891906123a1565b9150611196565b82516111429063f511231560e01b6114b5565b1561117d578251602084015160405163f511231560e01b81526001600160a01b039092169163f5112315916110e79160040190815260200190565b60405163f3c0936360e01b815260040160405180910390fd5b818360600151146111ca576060830151604051633840fc0160e01b8152610a0f918491600401918252602082015260400190565b50505b5050505050505050565b6000633b9aca008263ffffffff16116111ee575090565b428263ffffffff16111561120c576106f74263ffffffff84166123d0565b60405163e5084aed60e01b815263ffffffff808416600483015242166024820152604401610a0f565b919050565b61124261184e565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b336001600160a01b038216146112a657604051631144200360e31b81526001600160a01b0382166004820152602401610a0f565b506000908152602081905260409020805460ff19166001179055565b60006001600160a01b0384163b156113bd57600080856001600160a01b0316631626ba7e60e01b86866040516024016112fc9291906123e3565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161133a9190612404565b600060405180830381855afa9150503d8060008114611375576040519150601f19603f3d011682016040523d82523d6000602084013e61137a565b606091505b509150915081801561138d575080516020145b80156113b457508051630b135d3f60e11b906113b290830160209081019084016123a1565b145b92505050611462565b600080600084516041036113e55750505060208201516040830151606084015160001a61143c565b845160400361141e57602085015160408601519093506001600160ff1b038116925061141660ff82901c601b612420565b91505061143c565b845160405163058676ad60e31b8152600401610a0f91815260200190565b611448868285856114d1565b6001600160a01b0316876001600160a01b03161493505050505b9392505050565b600081815b848110156114ac576114988287878481811061148c5761148c612433565b905060200201356114f9565b9150806114a481612449565b91505061146e565b50949350505050565b60006114c083611528565b80156114625750611462838361155b565b60008060006114e2878787876115e4565b915091506114ef816116a8565b5095945050505050565b6000818310611515576000828152602084905260409020611462565b6000838152602083905260409020611462565b600061153b826301ffc9a760e01b61155b565b80156106f75750611554826001600160e01b031961155b565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156115cd575060208210155b80156115d95750600081115b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561161b575060009050600361169f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561166f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116985760006001925092505061169f565b9150600090505b94509492505050565b60008160048111156116bc576116bc6119d0565b036116c45750565b60018160048111156116d8576116d86119d0565b036117255760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a0f565b6002816004811115611739576117396119d0565b036117865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a0f565b600381600481111561179a5761179a6119d0565b036117f25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a0f565b50565b6040805161012081018252600080825260208201819052918101919091526060810161181f61184e565b815260200161182c61184e565b8152600060208201819052604082018190526060820181905260809091015290565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b6001600160a01b03811681146117f257600080fd5b803561123581611880565b60008083601f8401126118b257600080fd5b50813567ffffffffffffffff8111156118ca57600080fd5b6020830191508360208285010111156118e257600080fd5b9250929050565b60008060008060008060008060a0898b03121561190557600080fd5b883561191081611880565b975060208901359650604089013567ffffffffffffffff8082111561193457600080fd5b6119408c838d016118a0565b909850965060608b013591508082111561195957600080fd5b818b0191508b601f83011261196d57600080fd5b81358181111561197c57600080fd5b8c60208260051b850101111561199157600080fd5b6020830196508095505060808b01359150808211156119af57600080fd5b506119bc8b828c016118a0565b999c989b5096995094979396929594505050565b634e487b7160e01b600052602160045260246000fd5b60048110611a0457634e487b7160e01b600052602160045260246000fd5b9052565b611a138282516119e6565b6020818101516001600160a01b03169083015260408082015190830152606090810151910152565b82815281516001600160a01b03166020820152610200810160208301516001600160a01b038116604084015250604083015163ffffffff81166060840152506060830151611a8c6080840182611a08565b506080830151610100611aa181850183611a08565b60a085015161018085015260c085015162ffffff166101a085015260e08501516101c0850152909301516101e09092019190915292915050565b600060208284031215611aed57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102c0810167ffffffffffffffff81118282101715611b2e57611b2e611af4565b60405290565b600060208284031215611b4657600080fd5b813567ffffffffffffffff80821115611b5e57600080fd5b818401915084601f830112611b7257600080fd5b813581811115611b8457611b84611af4565b604051601f8201601f19908116603f01168101908382118183101715611bac57611bac611af4565b81604052828152876020848701011115611bc557600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006102c082019050611bf98284516119e6565b6020830151611c1360208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151611c3b608084018215159052565b5060a083015160a083015260c0830151611c6060c08401826001600160a01b03169052565b5060e083810151908301526101008084015190830152610120808401519083015261014080840151908301526101608084015162ffffff16908301526101808084015163ffffffff16908301526101a08084015164ffffffffff16908301526101c0808401516001600160a01b03908116918401919091526101e0808501518216908401526102008085015190840152610220808501511515908401526102408085015190840152610260808501519084015261028080850151908401526102a08085015191821681850152905b505092915050565b600481106117f257600080fd5b803561123581611d36565b80151581146117f257600080fd5b803561123581611d4e565b62ffffff811681146117f257600080fd5b803561123581611d67565b63ffffffff811681146117f257600080fd5b803561123581611d83565b64ffffffffff811681146117f257600080fd5b803561123581611da0565b60006102c08284031215611dd157600080fd5b611dd9611b0a565b611de283611d43565b8152611df060208401611895565b60208201526040830135604082015260608301356060820152611e1560808401611d5c565b608082015260a083013560a0820152611e3060c08401611895565b60c082015260e08381013590820152610100808401359082015261012080840135908201526101408084013590820152610160611e6e818501611d78565b90820152610180611e80848201611d95565b908201526101a0611e92848201611db3565b908201526101c0611ea4848201611895565b908201526101e0611eb6848201611895565b908201526102008381013590820152610220611ed3818501611d5c565b908201526102408381013590820152610260808401359082015261028080840135908201526102a0611f06818501611895565b908201529392505050565b60005b83811015611f2c578181015183820152602001611f14565b50506000910152565b60008151808452611f4d816020860160208601611f11565b601f01601f19169290920160200192915050565b6020815260006114626020830184611f35565b60008060408385031215611f8757600080fd5b50508035926020909101359150565b600060208284031215611fa857600080fd5b6040516020810181811067ffffffffffffffff82111715611fcb57611fcb611af4565b6040529135825250919050565b60006102c08284031215611feb57600080fd5b50919050565b805161123581611d36565b805161123581611880565b805161123581611d4e565b805161123581611d67565b805161123581611d83565b805161123581611da0565b60006102c0828403121561204657600080fd5b61204e611b0a565b61205783611ff1565b815261206560208401611ffc565b6020820152604083015160408201526060830151606082015261208a60808401612007565b608082015260a083015160a08201526120a560c08401611ffc565b60c082015260e083810151908201526101008084015190820152610120808401519082015261014080840151908201526101606120e3818501612012565b908201526101806120f584820161201d565b908201526101a0612107848201612028565b908201526101c0612119848201611ffc565b908201526101e061212b848201611ffc565b908201526102008381015190820152610220612148818501612007565b908201526102408381015190820152610260808401519082015261028080840151908201526102a0611f06818501611ffc565b6001600160a01b039390931683526020830191909152604082015260600190565b828152600082516121b4816020850160208701611f11565b919091016020019392505050565b6000602082840312156121d457600080fd5b813561146281611880565b6102c081016121f6826121f185611d43565b6119e6565b61220260208401611895565b6001600160a01b038116602084015250604083013560408301526060830135606083015261223260808401611d5c565b1515608083015260a0838101359083015261224f60c08401611895565b6001600160a01b031660c083015260e08381013590830152610100808401359083015261012080840135908301526101408084013590830152610160612296818501611d78565b62ffffff16908301526101806122ad848201611d95565b63ffffffff16908301526101a06122c5848201611db3565b64ffffffffff16908301526101c06122de848201611895565b6001600160a01b0316908301526101e06122f9848201611895565b6001600160a01b031690830152610200838101359083015261022061231f818501611d5c565b1515908301526102408381013590830152610260808401359083015261028080840135908301526102a0612354818501611895565b6001600160a01b03811684830152611d2e565b60006020828403121561237957600080fd5b815161146281611d4e565b60006020828403121561239657600080fd5b815161146281611880565b6000602082840312156123b357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106f7576106f76123ba565b8281526040602082015260006123fc6040830184611f35565b949350505050565b60008251612416818460208701611f11565b9190910192915050565b808201808211156106f7576106f76123ba565b634e487b7160e01b600052603260045260246000fd5b60006001820161245b5761245b6123ba565b506001019056fea2646970667358221220d1c79fb65b29e4e9487c9bdf24e8c0288745b6e97771284c74f63ca87e7f741164736f6c63430008100033","sourceMap":"421:8910:99:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6669:2659;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;2392:46:98;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;4587:14:137;;4580:22;4562:41;;4550:2;4535:18;2392:46:98;4422:187:137;6453:153:99;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6169:135::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1213:41:98:-;;;;;;;;12722:25:137;;;12710:2;12695:18;1213:41:98;12576:177:137;1322:27:98;;;;;;;;-1:-1:-1;;;;;12938:32:137;;;12920:51;;12908:2;12893:18;1322:27:98;12758:219:137;1445:49:98;;;;;5840:137;;;;;;:::i;:::-;;:::i;:::-;;1406:33;;;;;5290:322;;;;;;:::i;:::-;;:::i;605:600:99:-;;649:556;605:600;;1355:45:98;;;;;5745:273:99;;;;;;:::i;:::-;;:::i;1260:55:98:-;;;;;5338:164:99;;;;;;:::i;:::-;;:::i;1501:108:98:-;;1550:59;1501:108;;490:38:99;;;;;;;;;;;;;;;-1:-1:-1;;;490:38:99;;;;;6669:2659;6909:20;6931:36;;:::i;:::-;7011:24;7038:32;7057:12;;7038:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7038:18:99;;-1:-1:-1;;;7038:32:99:i;:::-;7011:59;;7126:57;649:556;7173:8;7162:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;7126:16;:57::i;:::-;7111:72;;7228:1076;7257:8;7279:17;7310:12;7336:22;;7372:9;;7395:899;;;;;;;;7445:8;:26;;;-1:-1:-1;;;;;7395:899:99;;;;;7503:8;:21;;;7395:899;;;;7575:8;:40;;;7395:899;;;;;;7661:8;:35;;;7395:899;;;;7728:8;:21;;;7395:899;;;;7789:8;:29;;;7395:899;;;;7854:8;:25;;;7395:899;;;;7909:8;:19;;;7395:899;;;;;;7963:8;:24;;;-1:-1:-1;;;;;7395:899:99;;;;;8015:8;:17;;;-1:-1:-1;;;;;7395:899:99;;;;;8059:8;:16;;;7395:899;;;;;;8112:8;:26;;;7395:899;;;;8168:8;:19;;;7395:899;;;;8212:8;:14;;;7395:899;;;;8258:8;:21;;;-1:-1:-1;;;;;7395:899:99;;;;7228:15;:1076::i;:::-;8363:958;;;;;;;;8405:8;:16;;;:47;;8444:8;8405:47;;;8424:8;:17;;;8405:47;-1:-1:-1;;;;;8363:958:99;;;;;8476:8;:16;;;:47;;8506:8;:17;;;8476:47;;;8495:8;8476:47;-1:-1:-1;;;;;8363:958:99;;;;;8547:41;8564:8;:23;;;8547:16;:41::i;:::-;8363:958;;;;;;8614:239;;;;;;;;8659:8;:27;;;8614:239;;;;;;;;:::i;:::-;;;;;8718:8;:26;;;-1:-1:-1;;;;;8614:239:99;;;;;8766:8;:21;;;8614:239;;;;8813:8;:25;;;8614:239;;;8363:958;;;;8875:133;8924:8;:22;;;8972:8;:21;;;8875:16;:133::i;:::-;8363:958;;;;9043:8;:28;;;8363:958;;;;9106:8;:28;;;8363:958;;;;;;9164:8;:16;;;:57;;9219:1;9164:57;;;9183:8;:25;;;9164:57;8363:958;;;;9253:8;:16;;;:57;;9285:8;:25;;;9253:57;;;9280:1;9253:57;8363:958;;;8351:970;;6969:2359;6669:2659;;;;;;;;;;;:::o;6453:153::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6563:36:99;;-1:-1:-1;;6563:36:99;;;;;;;;;;:::i;:::-;6556:43;6453:153;-1:-1:-1;;6453:153:99:o;6169:135::-;6246:12;6288:8;6277:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;6270:27;;6169:135;;;:::o;5840:137:98:-;5915:55;;-1:-1:-1;;;5915:55:98;;-1:-1:-1;;;;;5915:12:98;:24;;;;:55;;5940:10;;5952;;5964:5;;5915:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5840:137;;:::o;5290:322::-;5377:7;5454:30;1550:59;5565:13;5554:25;;;;;;18336:13:137;18318:32;;18306:2;18291:18;;18108:248;5554:25:98;;;;-1:-1:-1;;5554:25:98;;;;;;;;;;5496:97;;;5554:25;5496:97;;:::i;:::-;;;;;;;;;;;;;5486:108;;;;;;5413:191;;;;;;;;-1:-1:-1;;;18983:27:137;;19035:1;19026:11;;19019:27;;;;19071:2;19062:12;;19055:28;19108:2;19099:12;;18725:392;5413:191:98;;;;;;;;;;;;;5403:202;;;;;;5396:209;;5290:322;;;:::o;5745:273:99:-;5813:20;5860:25;5876:8;5860:15;:25::i;:::-;5845:40;-1:-1:-1;5895:46:99;5845:40;5923:17;;;;;;;;:::i;:::-;5895:13;:46::i;:::-;5983:17;;;;;;;;:::i;:::-;-1:-1:-1;;;;;5956:55:99;5969:12;5956:55;6002:8;5956:55;;;;;;:::i;:::-;;;;;;;;5745:273;;;:::o;5338:164::-;5412:7;5438:57;649:556;5485:8;5474:20;;;;;;;;:::i;7195:332:98:-;7322:7;7399:16;7461;7479:15;7427:81;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7417:92;;;;;;7358:161;;;;;;;;-1:-1:-1;;;18983:27:137;;19035:1;19026:11;;19019:27;;;;19071:2;19062:12;;19055:28;19108:2;19099:12;;18725:392;7358:161:98;;;;;;;;;;;;;7348:172;;;;;;7341:179;;7195:332;;;;:::o;9037:5154::-;9350:8;:21;;;-1:-1:-1;;;;;9336:35:98;:10;-1:-1:-1;;;;;9336:35:98;;9332:155;;9452:21;;;;9394:82;;-1:-1:-1;;;9394:82:98;;9426:10;9394:82;;;22256:34:137;-1:-1:-1;;;;;22326:15:137;;;22306:18;;;22299:43;22191:18;;9394:82:98;;;;;;;;9332:155;9512:21;;;;9501:57;;-1:-1:-1;;;9501:57:98;;-1:-1:-1;;;;;22545:32:137;;;9501:57:98;;;22527:51:137;266:28:82;22594:18:137;;;22587:34;9501:3:98;:10;;;;;;22500:18:137;;9501:57:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9496:178;;9610:21;;;;9581:82;;-1:-1:-1;;;9581:82:98;;-1:-1:-1;;;;;22545:32:137;;;9581:82:98;;;22527:51:137;266:28:82;22594:18:137;;;22587:34;22500:18;;9581:82:98;22353:274:137;9496:178:98;9786:1;9753:34;;;9749:1025;;9849:13;:27;;;;;;;;;;;;;9844:293;;9901:83;9941:8;:17;;;9960:12;9974:9;;9901:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9901:39:98;;-1:-1:-1;;;9901:83:98:i;:::-;9896:227;;10062:17;;;;10015:89;;-1:-1:-1;;;10015:89:98;;-1:-1:-1;;;;;22545:32:137;;;10015:89:98;;;22527:51:137;22594:18;;;22587:34;;;22500:18;;10015:89:98;22353:274:137;9896:227:98;9749:1025;;;10206:25;10234:287;10272:235;;;;;;;;10333:155;10399:22;;10453:12;10333:32;:155::i;:::-;10272:235;;10234:20;:287::i;:::-;10206:315;;10540:88;10580:8;:17;;;10599;10618:9;;10540:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10540:39:98;;-1:-1:-1;;;10540:88:98:i;:::-;10535:229;;10702:17;;;;10655:94;;-1:-1:-1;;;10655:94:98;;-1:-1:-1;;;;;22545:32:137;;;10655:94:98;;;22527:51:137;22594:18;;;22587:34;;;22500:18;;10655:94:98;22353:274:137;10535:229:98;10153:621;9749:1025;10851:8;-1:-1:-1;;;;;10830:29:98;:8;:17;;;-1:-1:-1;;;;;10830:29:98;;10826:104;;10882:37;;-1:-1:-1;;;10882:37:98;;-1:-1:-1;;;;;12938:32:137;;10882:37:98;;;12920:51:137;12893:18;;10882:37:98;12758:219:137;10826:104:98;10982:17;11003:1;10982:22;10978:500;;11024:26;;;;:31;11020:152;;11128:8;:26;;;11082:75;;-1:-1:-1;;;11082:75:98;;;;;;12722:25:137;;12710:2;12695:18;;12576:177;11020:152:98;10978:500;;;11227:8;:26;;;11206:17;:47;11202:266;;11277:26;;;;:31;;;:52;;;11313:8;:16;;;11312:17;11277:52;11273:181;;;11406:8;:26;;;11360:75;;-1:-1:-1;;;11360:75:98;;;;;;12722:25:137;;12710:2;12695:18;;12576:177;11273:181:98;11552:8;:19;;;11533:38;;:15;:38;11529:146;;11642:19;;;;11594:70;;-1:-1:-1;;;11594:70:98;;11613:15;11594:70;;;23445:25:137;23518:12;23506:25;;;23486:18;;;23479:53;23418:18;;11594:70:98;23272:266:137;11529:146:98;11731:12;-1:-1:-1;;;;;11731:26:98;;11758:8;:17;;;11777:8;:19;;;11798:8;:14;;;11731:82;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11726:296;;11891:8;:17;;;11938:8;:19;;;11982:8;:14;;;11836:175;;-1:-1:-1;;;11836:175:98;;;;;;;;;;:::i;11726:296::-;12095:24;;;;-1:-1:-1;;;;;12095:38:98;;;;;:78;;;12149:8;:24;;;-1:-1:-1;;;;;12137:36:98;:8;-1:-1:-1;;;;;12137:36:98;;;12095:78;12091:198;;;12251:24;;;;12196:82;;-1:-1:-1;;;12196:82:98;;-1:-1:-1;;;;;22274:15:137;;;12196:82:98;;;22256:34:137;22326:15;;;22306:18;;;22299:43;22191:18;;12196:82:98;22044:304:137;12091:198:98;12303:8;:29;;;12336:1;12303:34;12299:554;;12438:12;-1:-1:-1;;;;;12438:24:98;;12463:8;:17;;;12482:8;:19;;;12503:8;:14;;;12438:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12299:554;;;12730:17;;;;12749:25;;;;12776:21;;;;12799:29;;;;12684:158;;-1:-1:-1;;;12684:158:98;;-1:-1:-1;;;;;23792:32:137;;;12684:158:98;;;23774:51:137;23841:18;;;23834:34;;;;23884:18;;;23877:34;;;;23927:18;;;23920:34;12684:14:98;:28;;;;;;23746:19:137;;12684:158:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12299:554;12923:8;:40;;;12919:1266;;;13091:26;;13056:62;;-1:-1:-1;;;13056:62:98;;-1:-1:-1;;;;;12938:32:137;;;13056:62:98;;;12920:51:137;12979:26:98;;;;13056:6;:34;;;;;;12893:18:137;;13056:62:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13019:99;-1:-1:-1;;;;;;13136:31:98;;;13132:717;;13319:26;;13356:21;;;;13257:139;;-1:-1:-1;;;13257:139:98;;-1:-1:-1;;;;;13257:32:98;;;;;:139;;;;-1:-1:-1;;;;;22545:32:137;;;;22527:51;;22609:2;22594:18;;22587:34;22515:2;22500:18;;22353:274;13257:139:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13236:160;;13132:717;;;13453:26;;13421:87;;-1:-1:-1;;;13421:31:98;:87::i;:::-;13417:432;;;13602:26;;13650:21;;;;13593:79;;-1:-1:-1;;;13593:79:98;;-1:-1:-1;;;;;13593:56:98;;;;;;:79;;;;12722:25:137;;;12710:2;12695:18;;12576:177;13417:432:98;13801:33;;-1:-1:-1;;;13801:33:98;;;;;;;;;;;13417:432;13906:18;13867:8;:35;;;:57;13863:312;;14106:35;;;;13991:169;;-1:-1:-1;;;13991:169:98;;;;14056:18;;13991:169;;24898:25:137;;;24954:2;24939:18;;24932:34;24886:2;24871:18;;24724:248;13863:312:98;12965:1220;;12919:1266;9037:5154;;;;;;;;:::o;8155:478::-;8227:6;8267:3;8249:14;:21;;;8245:382;;-1:-1:-1;8326:14:98;8155:478::o;8245:382::-;8378:15;8361:14;:32;;;8357:270;;;8452:41;8478:15;8452:23;;;:41;:::i;8357:270::-;8532:84;;-1:-1:-1;;;8532:84:98;;25422:10:137;25459:15;;;8532:84:98;;;25441:34:137;8597:15:98;25511::137;25491:18;;;25484:43;25385:18;;8532:84:98;25242:291:137;8357:270:98;8155:478;;;:::o;2542:160:0:-;2618:12;;:::i;:::-;-1:-1:-1;2649:46:0;;;;;;;;-1:-1:-1;2649:46:0;;;-1:-1:-1;;;;;2649:46:0;;;;;;;;;;;;;;;;;;;;2542:160::o;7748:238:98:-;7834:10;-1:-1:-1;;;;;7834:22:98;;;7830:105;;7879:45;;-1:-1:-1;;;7879:45:98;;-1:-1:-1;;;;;12938:32:137;;7879:45:98;;;12920:51:137;12893:18;;7879:45:98;12758:219:137;7830:105:98;-1:-1:-1;7945:13:98;:27;;;;;;;;;;:34;;-1:-1:-1;;7945:34:98;7975:4;7945:34;;;7748:238::o;1541:1696:92:-;1677:4;-1:-1:-1;;;;;1759:18:92;;;:22;1755:1476;;1798:12;1812:19;1835:6;-1:-1:-1;;;;;1835:17:92;1893:34;;;1929:4;1935:9;1870:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1870:75:92;;;;;;;;;;;;;;-1:-1:-1;;;;;1870:75:92;-1:-1:-1;;;;;;1870:75:92;;;;;;;;;;1835:124;;;;1870:75;1835:124;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1797:162;;;;1996:7;:46;;;;;2023:6;:13;2040:2;2023:19;1996:46;:142;;;;-1:-1:-1;2062:29:92;;-1:-1:-1;;;2103:34:92;2062:29;;;;;;;;;;;;:::i;:::-;:76;1996:142;1973:165;;;;;;1755:1476;2226:9;2249;2272:7;2348:9;:16;2368:2;2348:22;2344:817;;-1:-1:-1;;;2447:4:92;2432:20;;2426:27;2500:4;2485:20;;2479:27;2561:4;2546:20;;2540:27;2537:1;2532:36;2344:817;;;2686:9;:16;2706:2;2686:22;2682:479;;2814:4;2799:20;;2793:27;2868:4;2853:20;;2847:27;2793;;-1:-1:-1;;;;;;2914:80:92;;;-1:-1:-1;3022:25:92;3038:3;3023:18;;;3045:2;3022:25;:::i;:::-;3012:36;;2710:353;2682:479;;;3127:9;:16;3094:52;;-1:-1:-1;;;3094:52:92;;;;;;12722:25:137;;12710:2;12695:18;;12576:177;2682:479:92;3192:28;3206:4;3212:1;3215;3218;3192:13;:28::i;:::-;-1:-1:-1;;;;;3182:38:92;:6;-1:-1:-1;;;;;3182:38:92;;3175:45;;;;;1755:1476;1541:1696;;;;;:::o;2331:300:66:-;2424:7;2466:4;2424:7;2480:116;2500:16;;;2480:116;;;2552:33;2562:12;2576:5;;2582:1;2576:8;;;;;;;:::i;:::-;;;;;;;2552:9;:33::i;:::-;2537:48;-1:-1:-1;2518:3:66;;;;:::i;:::-;;;;2480:116;;;-1:-1:-1;2612:12:66;2331:300;-1:-1:-1;;;;2331:300:66:o;1349:282:68:-;1436:4;1543:23;1558:7;1543:14;:23::i;:::-;:81;;;;;1570:54;1603:7;1612:11;1570:32;:54::i;6598:232:65:-;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:65;6598:232;-1:-1:-1;;;;;6598:232:65:o;9205:147:66:-;9268:7;9298:1;9294;:5;:51;;9426:13;9517:15;;;9552:4;9545:15;;;9598:4;9582:21;;9294:51;;;9426:13;9517:15;;;9552:4;9545:15;;;9598:4;9582:21;;9302:20;9358:261;704:427:68;768:4;975:68;1008:7;-1:-1:-1;;;975:32:68;:68::i;:::-;:149;;;;-1:-1:-1;1060:64:68;1093:7;-1:-1:-1;;;;;;1060:32:68;:64::i;:::-;1059:65;956:168;704:427;-1:-1:-1;;704:427:68:o;4421:647::-;4592:71;;;-1:-1:-1;;;;;;26687:33:137;;4592:71:68;;;;26669:52:137;;;;4592:71:68;;;;;;;;;;26642:18:137;;;;4592:71:68;;;;;;;;;-1:-1:-1;;;;;4592:71:68;-1:-1:-1;;;4592:71:68;;;4871:20;;4523:4;;4592:71;4523:4;;;;;;4592:71;4523:4;;4871:20;4836:7;4829:5;4818:86;4807:97;;4931:16;4917:30;;4981:4;4975:11;4960:26;;5013:7;:29;;;;;5038:4;5024:10;:18;;5013:29;:48;;;;;5060:1;5046:11;:15;5013:48;5006:55;4421:647;-1:-1:-1;;;;;;;4421:647:68:o;5009:1456:65:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:65;;-1:-1:-1;6123:30:65;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;26959:25:137;;;27032:4;27020:17;;27000:18;;;26993:45;;;;27054:18;;;27047:34;;;27097:18;;;27090:34;;;6276:24:65;;26931:19:137;;6276:24:65;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:65;;-1:-1:-1;;6276:24:65;;;-1:-1:-1;;;;;;;6314:20:65;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:65;;-1:-1:-1;5009:1456:65;;;;;;;;:::o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:65;;27337:2:137;788:34:65;;;27319:21:137;27376:2;27356:18;;;27349:30;27415:26;27395:18;;;27388:54;27459:18;;788:34:65;27135:348:137;730:345:65;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:65;;27690:2:137;903:41:65;;;27672:21:137;27729:2;27709:18;;;27702:30;27768:33;27748:18;;;27741:61;27819:18;;903:41:65;27488:355:137;839:236:65;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:65;;28050:2:137;1020:44:65;;;28032:21:137;28089:2;28069:18;;;28062:30;28128:34;28108:18;;;28101:62;-1:-1:-1;;;28179:18:137;;;28172:32;28221:19;;1020:44:65;27848:398:137;961:114:65;570:511;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:137:-;-1:-1:-1;;;;;89:31:137;;79:42;;69:70;;135:1;132;125:12;150:134;218:20;;247:31;218:20;247:31;:::i;289:347::-;340:8;350:6;404:3;397:4;389:6;385:17;381:27;371:55;;422:1;419;412:12;371:55;-1:-1:-1;445:20:137;;488:18;477:30;;474:50;;;520:1;517;510:12;474:50;557:4;549:6;545:17;533:29;;609:3;602:4;593:6;585;581:19;577:30;574:39;571:59;;;626:1;623;616:12;571:59;289:347;;;;;:::o;641:1394::-;785:6;793;801;809;817;825;833;841;894:3;882:9;873:7;869:23;865:33;862:53;;;911:1;908;901:12;862:53;950:9;937:23;969:31;994:5;969:31;:::i;:::-;1019:5;-1:-1:-1;1071:2:137;1056:18;;1043:32;;-1:-1:-1;1126:2:137;1111:18;;1098:32;1149:18;1179:14;;;1176:34;;;1206:1;1203;1196:12;1176:34;1245:58;1295:7;1286:6;1275:9;1271:22;1245:58;:::i;:::-;1322:8;;-1:-1:-1;1219:84:137;-1:-1:-1;1410:2:137;1395:18;;1382:32;;-1:-1:-1;1426:16:137;;;1423:36;;;1455:1;1452;1445:12;1423:36;1493:8;1482:9;1478:24;1468:34;;1540:7;1533:4;1529:2;1525:13;1521:27;1511:55;;1562:1;1559;1552:12;1511:55;1602:2;1589:16;1628:2;1620:6;1617:14;1614:34;;;1644:1;1641;1634:12;1614:34;1697:7;1692:2;1682:6;1679:1;1675:14;1671:2;1667:23;1663:32;1660:45;1657:65;;;1718:1;1715;1708:12;1657:65;1749:2;1745;1741:11;1731:21;;1771:6;1761:16;;;1830:3;1819:9;1815:19;1802:33;1786:49;;1860:2;1850:8;1847:16;1844:36;;;1876:1;1873;1866:12;1844:36;;1915:60;1967:7;1956:8;1945:9;1941:24;1915:60;:::i;:::-;641:1394;;;;-1:-1:-1;641:1394:137;;-1:-1:-1;641:1394:137;;;;;;1994:8;-1:-1:-1;;;641:1394:137:o;2248:127::-;2309:10;2304:3;2300:20;2297:1;2290:31;2340:4;2337:1;2330:15;2364:4;2361:1;2354:15;2380:236;2460:1;2453:5;2450:12;2440:143;;2505:10;2500:3;2496:20;2493:1;2486:31;2540:4;2537:1;2530:15;2568:4;2565:1;2558:15;2440:143;2592:18;;2380:236::o;2621:302::-;2680:43;2719:3;2711:5;2705:12;2680:43;:::i;:::-;2776:4;2765:16;;;2759:23;-1:-1:-1;;;;;2755:49:137;2739:14;;;2732:73;2854:4;2843:16;;;2837:23;2821:14;;;2814:47;2910:4;2899:16;;;2893:23;2877:14;;2870:47;2621:302::o;3025:1111::-;3248:25;;;3301:13;;-1:-1:-1;;;;;2106:31:137;3331:2;3316:18;;2094:44;3235:3;3220:19;;3382:2;3370:15;;3364:22;-1:-1:-1;;;;;2106:31:137;;3443:2;3428:18;;2094:44;-1:-1:-1;3496:2:137;3484:15;;3478:22;2225:10;2214:22;;3558:2;3543:18;;2202:35;3509:53;3611:2;3603:6;3599:15;3593:22;3624:60;3679:3;3668:9;3664:19;3648:14;3624:60;:::i;:::-;;3733:3;3725:6;3721:16;3715:23;3757:3;3769:59;3824:2;3813:9;3809:18;3793:14;3769:59;:::i;:::-;3883:4;3871:17;;3865:24;3859:3;3844:19;;3837:53;3939:4;3927:17;;3921:24;3004:8;2993:20;4003:3;3988:19;;2981:33;4063:4;4051:17;;4045:24;4039:3;4024:19;;4017:53;4113:15;;;4107:22;4101:3;4086:19;;;4079:51;;;;3025:1111;;-1:-1:-1;;3025:1111:137:o;4141:180::-;4200:6;4253:2;4241:9;4232:7;4228:23;4224:32;4221:52;;;4269:1;4266;4259:12;4221:52;-1:-1:-1;4292:23:137;;4141:180;-1:-1:-1;4141:180:137:o;4614:127::-;4675:10;4670:3;4666:20;4663:1;4656:31;4706:4;4703:1;4696:15;4730:4;4727:1;4720:15;4746:247;4813:2;4807:9;4855:3;4843:16;;4889:18;4874:34;;4910:22;;;4871:62;4868:88;;;4936:18;;:::i;:::-;4972:2;4965:22;4746:247;:::o;4998:921::-;5066:6;5119:2;5107:9;5098:7;5094:23;5090:32;5087:52;;;5135:1;5132;5125:12;5087:52;5175:9;5162:23;5204:18;5245:2;5237:6;5234:14;5231:34;;;5261:1;5258;5251:12;5231:34;5299:6;5288:9;5284:22;5274:32;;5344:7;5337:4;5333:2;5329:13;5325:27;5315:55;;5366:1;5363;5356:12;5315:55;5402:2;5389:16;5424:2;5420;5417:10;5414:36;;;5430:18;;:::i;:::-;5505:2;5499:9;5473:2;5559:13;;-1:-1:-1;;5555:22:137;;;5579:2;5551:31;5547:40;5535:53;;;5603:18;;;5623:22;;;5600:46;5597:72;;;5649:18;;:::i;:::-;5689:10;5685:2;5678:22;5724:2;5716:6;5709:18;5764:7;5759:2;5754;5750;5746:11;5742:20;5739:33;5736:53;;;5785:1;5782;5775:12;5736:53;5841:2;5836;5832;5828:11;5823:2;5815:6;5811:15;5798:46;5886:1;5864:15;;;5881:2;5860:24;5853:35;;;;-1:-1:-1;5868:6:137;4998:921;-1:-1:-1;;;;;4998:921:137:o;6025:2446::-;6171:4;6213:3;6202:9;6198:19;6190:27;;6226:50;6266:9;6257:6;6251:13;6226:50;:::i;:::-;6323:4;6315:6;6311:17;6305:24;6338:54;6386:4;6375:9;6371:20;6357:12;-1:-1:-1;;;;;2106:31:137;2094:44;;2040:104;6338:54;;6448:4;6440:6;6436:17;6430:24;6423:4;6412:9;6408:20;6401:54;6511:4;6503:6;6499:17;6493:24;6486:4;6475:9;6471:20;6464:54;6567:4;6559:6;6555:17;6549:24;6582:53;6629:4;6618:9;6614:20;6598:14;4396:13;4389:21;4377:34;;4326:91;6582:53;;6691:4;6683:6;6679:17;6673:24;6666:4;6655:9;6651:20;6644:54;6747:4;6739:6;6735:17;6729:24;6762:56;6812:4;6801:9;6797:20;6781:14;-1:-1:-1;;;;;2106:31:137;2094:44;;2040:104;6762:56;-1:-1:-1;6874:4:137;6862:17;;;6856:24;6834:20;;;6827:54;6900:6;6948:15;;;6942:22;6922:18;;;6915:50;6984:6;7032:15;;;7026:22;7006:18;;;6999:50;7068:6;7116:15;;;7110:22;7090:18;;;7083:50;7152:6;7195:15;;;7189:22;3004:8;2993:20;7254:18;;;2981:33;7292:6;7335:15;;;7329:22;2225:10;2214:22;7394:18;;;2202:35;7432:6;7475:15;;;7469:22;6000:12;5989:24;7534:18;;;5977:37;7572:6;7615:15;;;7609:22;-1:-1:-1;;;;;2106:31:137;;;7675:18;;;2094:44;;;;7713:6;7756:15;;;7750:22;2106:31;;7816:18;;;2094:44;7854:6;7902:15;;;7896:22;7876:18;;;7869:50;7939:6;7982:16;;;7976:23;4396:13;4389:21;8040:19;;;4377:34;8080:6;8129:16;;;8123:23;8102:19;;;8095:52;8167:6;8216:16;;;8210:23;8189:19;;;8182:52;8254:6;8303:16;;;8297:23;8276:19;;;8269:52;8341:6;8384:16;;;8378:23;2106:31;;;8445:19;;;2094:44;8341:6;8410:55;;;6025:2446;;;;:::o;8476:107::-;8557:1;8550:5;8547:12;8537:40;;8573:1;8570;8563:12;8588:146;8662:20;;8691:37;8662:20;8691:37;:::i;8739:118::-;8825:5;8818:13;8811:21;8804:5;8801:32;8791:60;;8847:1;8844;8837:12;8862:128;8927:20;;8956:28;8927:20;8956:28;:::i;8995:119::-;9080:8;9073:5;9069:20;9062:5;9059:31;9049:59;;9104:1;9101;9094:12;9119:132;9186:20;;9215:30;9186:20;9215:30;:::i;9256:121::-;9341:10;9334:5;9330:22;9323:5;9320:33;9310:61;;9367:1;9364;9357:12;9382:132;9449:20;;9478:30;9449:20;9478:30;:::i;9519:123::-;9604:12;9597:5;9593:24;9586:5;9583:35;9573:63;;9632:1;9629;9622:12;9647:132;9714:20;;9743:30;9714:20;9743:30;:::i;9784:2035::-;9870:6;9923:3;9911:9;9902:7;9898:23;9894:33;9891:53;;;9940:1;9937;9930:12;9891:53;9966:17;;:::i;:::-;10006:35;10031:9;10006:35;:::i;:::-;9999:5;9992:50;10074:38;10108:2;10097:9;10093:18;10074:38;:::i;:::-;10069:2;10062:5;10058:14;10051:62;10173:2;10162:9;10158:18;10145:32;10140:2;10133:5;10129:14;10122:56;10238:2;10227:9;10223:18;10210:32;10205:2;10198:5;10194:14;10187:56;10276:36;10307:3;10296:9;10292:19;10276:36;:::i;:::-;10270:3;10263:5;10259:15;10252:61;10374:3;10363:9;10359:19;10346:33;10340:3;10333:5;10329:15;10322:58;10413:39;10447:3;10436:9;10432:19;10413:39;:::i;:::-;10407:3;10396:15;;10389:64;10514:3;10499:19;;;10486:33;10469:15;;;10462:58;10539:3;10587:18;;;10574:32;10558:14;;;10551:56;10626:3;10674:18;;;10661:32;10645:14;;;10638:56;10713:3;10761:18;;;10748:32;10732:14;;;10725:56;10800:3;10835:37;10853:18;;;10835:37;:::i;:::-;10819:14;;;10812:61;10892:3;10927:37;10945:18;;;10927:37;:::i;:::-;10911:14;;;10904:61;10984:3;11019:37;11037:18;;;11019:37;:::i;:::-;11003:14;;;10996:61;11076:3;11111:38;11130:18;;;11111:38;:::i;:::-;11095:14;;;11088:62;11169:3;11204:38;11223:18;;;11204:38;:::i;:::-;11188:14;;;11181:62;11262:3;11310:18;;;11297:32;11281:14;;;11274:56;11350:3;11386:36;11402:19;;;11386:36;:::i;:::-;11369:15;;;11362:61;11443:3;11492:19;;;11479:33;11462:15;;;11455:58;11533:3;11582:19;;;11569:33;11552:15;;;11545:58;11623:3;11672:19;;;11659:33;11642:15;;;11635:58;11713:3;11749:39;11768:19;;;11749:39;:::i;:::-;11732:15;;;11725:64;11736:5;9784:2035;-1:-1:-1;;;9784:2035:137:o;11824:250::-;11909:1;11919:113;11933:6;11930:1;11927:13;11919:113;;;12009:11;;;12003:18;11990:11;;;11983:39;11955:2;11948:10;11919:113;;;-1:-1:-1;;12066:1:137;12048:16;;12041:27;11824:250::o;12079:270::-;12120:3;12158:5;12152:12;12185:6;12180:3;12173:19;12201:76;12270:6;12263:4;12258:3;12254:14;12247:4;12240:5;12236:16;12201:76;:::i;:::-;12331:2;12310:15;-1:-1:-1;;12306:29:137;12297:39;;;;12338:4;12293:50;;12079:270;-1:-1:-1;;12079:270:137:o;12354:217::-;12501:2;12490:9;12483:21;12464:4;12521:44;12561:2;12550:9;12546:18;12538:6;12521:44;:::i;13217:248::-;13285:6;13293;13346:2;13334:9;13325:7;13321:23;13317:32;13314:52;;;13362:1;13359;13352:12;13314:52;-1:-1:-1;;13385:23:137;;;13455:2;13440:18;;;13427:32;;-1:-1:-1;13217:248:137:o;13697:445::-;13788:6;13841:2;13829:9;13820:7;13816:23;13812:32;13809:52;;;13857:1;13854;13847:12;13809:52;13890:2;13884:9;13932:2;13924:6;13920:15;14001:6;13989:10;13986:22;13965:18;13953:10;13950:34;13947:62;13944:88;;;14012:18;;:::i;:::-;14048:2;14041:22;14087:23;;14072:39;;-1:-1:-1;14079:6:137;13697:445;-1:-1:-1;13697:445:137:o;14380:196::-;14468:6;14521:3;14509:9;14500:7;14496:23;14492:33;14489:53;;;14538:1;14535;14528:12;14489:53;-1:-1:-1;14561:9:137;14380:196;-1:-1:-1;14380:196:137:o;14805:150::-;14890:13;;14912:37;14890:13;14912:37;:::i;14960:138::-;15039:13;;15061:31;15039:13;15061:31;:::i;15103:132::-;15179:13;;15201:28;15179:13;15201:28;:::i;15240:136::-;15318:13;;15340:30;15318:13;15340:30;:::i;15381:136::-;15459:13;;15481:30;15459:13;15481:30;:::i;15522:136::-;15600:13;;15622:30;15600:13;15622:30;:::i;15663:2090::-;15760:6;15813:3;15801:9;15792:7;15788:23;15784:33;15781:53;;;15830:1;15827;15820:12;15781:53;15856:17;;:::i;:::-;15896:46;15932:9;15896:46;:::i;:::-;15889:5;15882:61;15975:49;16020:2;16009:9;16005:18;15975:49;:::i;:::-;15970:2;15963:5;15959:14;15952:73;16078:2;16067:9;16063:18;16057:25;16052:2;16045:5;16041:14;16034:49;16136:2;16125:9;16121:18;16115:25;16110:2;16103:5;16099:14;16092:49;16174:47;16216:3;16205:9;16201:19;16174:47;:::i;:::-;16168:3;16161:5;16157:15;16150:72;16276:3;16265:9;16261:19;16255:26;16249:3;16242:5;16238:15;16231:51;16315:50;16360:3;16349:9;16345:19;16315:50;:::i;:::-;16309:3;16298:15;;16291:75;16420:3;16405:19;;;16399:26;16382:15;;;16375:51;16445:3;16486:18;;;16480:25;16464:14;;;16457:49;16525:3;16566:18;;;16560:25;16544:14;;;16537:49;16605:3;16646:18;;;16640:25;16624:14;;;16617:49;16685:3;16720:48;16749:18;;;16720:48;:::i;:::-;16704:14;;;16697:72;16788:3;16823:48;16852:18;;;16823:48;:::i;:::-;16807:14;;;16800:72;16891:3;16926:48;16955:18;;;16926:48;:::i;:::-;16910:14;;;16903:72;16994:3;17029:49;17059:18;;;17029:49;:::i;:::-;17013:14;;;17006:73;17098:3;17133:49;17163:18;;;17133:49;:::i;:::-;17117:14;;;17110:73;17202:3;17243:18;;;17237:25;17221:14;;;17214:49;17283:3;17319:47;17346:19;;;17319:47;:::i;:::-;17302:15;;;17295:72;17387:3;17429:19;;;17423:26;17406:15;;;17399:51;17470:3;17512:19;;;17506:26;17489:15;;;17482:51;17553:3;17595:19;;;17589:26;17572:15;;;17565:51;17636:3;17672:50;17702:19;;;17672:50;:::i;17758:345::-;-1:-1:-1;;;;;17978:32:137;;;;17960:51;;18042:2;18027:18;;18020:34;;;;18085:2;18070:18;;18063:34;17948:2;17933:18;;17758:345::o;18361:359::-;18548:6;18543:3;18536:19;18518:3;18584:6;18578:13;18600:73;18666:6;18661:2;18656:3;18652:12;18647:2;18639:6;18635:15;18600:73;:::i;:::-;18693:16;;;;18711:2;18689:25;;18361:359;-1:-1:-1;;;18361:359:137:o;19122:247::-;19181:6;19234:2;19222:9;19213:7;19209:23;19205:32;19202:52;;;19250:1;19247;19240:12;19202:52;19289:9;19276:23;19308:31;19333:5;19308:31;:::i;19374:2665::-;19564:3;19549:19;;19577:69;19553:9;19602:32;19627:6;19602:32;:::i;:::-;19577:69;:::i;:::-;19675:37;19706:4;19698:6;19694:17;19675:37;:::i;:::-;-1:-1:-1;;;;;2106:31:137;;19769:4;19754:20;;2094:44;19721:54;19838:4;19830:6;19826:17;19813:31;19806:4;19795:9;19791:20;19784:61;19908:4;19900:6;19896:17;19883:31;19876:4;19865:9;19861:20;19854:61;19946:34;19974:4;19966:6;19962:17;19946:34;:::i;:::-;4396:13;4389:21;20036:4;20021:20;;4377:34;20105:4;20093:17;;;20080:31;20058:20;;;20051:61;20143:37;20174:4;20162:17;;20143:37;:::i;:::-;-1:-1:-1;;;;;2106:31:137;20239:4;20224:20;;2094:44;20308:4;20296:17;;;20283:31;20261:20;;;20254:61;20334:6;20389:15;;;20376:29;20356:18;;;20349:57;20425:6;20480:15;;;20467:29;20447:18;;;20440:57;20516:6;20571:15;;;20558:29;20538:18;;;20531:57;20607:6;20644:34;20662:15;;;20644:34;:::i;:::-;3004:8;2993:20;20721:18;;;2981:33;20759:6;20796:34;20814:15;;;20796:34;:::i;:::-;2225:10;2214:22;20873:18;;;2202:35;20911:6;20948:34;20966:15;;;20948:34;:::i;:::-;6000:12;5989:24;21025:18;;;5977:37;21063:6;21100:35;21119:15;;;21100:35;:::i;:::-;-1:-1:-1;;;;;2106:31:137;21179:18;;;2094:44;21217:6;21254:35;21273:15;;;21254:35;:::i;:::-;-1:-1:-1;;;;;2106:31:137;21333:18;;;2094:44;21371:6;21426:15;;;21413:29;21393:18;;;21386:57;21463:6;21500:33;21516:16;;;21500:33;:::i;:::-;4396:13;4389:21;21574:19;;;4377:34;21614:6;21670:16;;;21657:30;21636:19;;;21629:59;21708:6;21764:16;;;21751:30;21730:19;;;21723:59;21802:6;21858:16;;;21845:30;21824:19;;;21817:59;21896:6;21933:36;21952:16;;;21933:36;:::i;:::-;-1:-1:-1;;;;;2106:31:137;;22013:19;;;2094:44;21978:55;2040:104;22632:245;22699:6;22752:2;22740:9;22731:7;22727:23;22723:32;22720:52;;;22768:1;22765;22758:12;22720:52;22800:9;22794:16;22819:28;22841:5;22819:28;:::i;23965:286::-;24070:6;24123:2;24111:9;24102:7;24098:23;24094:32;24091:52;;;24139:1;24136;24129:12;24091:52;24171:9;24165:16;24190:31;24215:5;24190:31;:::i;24535:184::-;24605:6;24658:2;24646:9;24637:7;24633:23;24629:32;24626:52;;;24674:1;24671;24664:12;24626:52;-1:-1:-1;24697:16:137;;24535:184;-1:-1:-1;24535:184:137:o;24977:127::-;25038:10;25033:3;25029:20;25026:1;25019:31;25069:4;25066:1;25059:15;25093:4;25090:1;25083:15;25109:128;25176:9;;;25197:11;;;25194:37;;;25211:18;;:::i;25538:288::-;25713:6;25702:9;25695:25;25756:2;25751;25740:9;25736:18;25729:30;25676:4;25776:44;25816:2;25805:9;25801:18;25793:6;25776:44;:::i;:::-;25768:52;25538:288;-1:-1:-1;;;;25538:288:137:o;25831:287::-;25960:3;25998:6;25992:13;26014:66;26073:6;26068:3;26061:4;26053:6;26049:17;26014:66;:::i;:::-;26096:16;;;;;25831:287;-1:-1:-1;;25831:287:137:o;26123:125::-;26188:9;;;26209:10;;;26206:36;;;26222:18;;:::i;26253:127::-;26314:10;26309:3;26305:20;26302:1;26295:31;26345:4;26342:1;26335:15;26369:4;26366:1;26359:15;26385:135;26424:3;26445:17;;;26442:43;;26465:18;;:::i;:::-;-1:-1:-1;26512:1:137;26501:13;;26385:135::o","linkReferences":{},"immutableReferences":{"67277":[{"start":434,"length":32},{"start":2359,"length":32}],"67279":[{"start":765,"length":32},{"start":1968,"length":32}],"67282":[{"start":487,"length":32},{"start":2659,"length":32}],"67285":[{"start":707,"length":32},{"start":1853,"length":32},{"start":3438,"length":32},{"start":3768,"length":32}],"67288":[{"start":610,"length":32},{"start":4132,"length":32}],"67291":[{"start":550,"length":32},{"start":3989,"length":32}]}},"methodIdentifiers":{"DOMAIN_SEPARATOR()":"3644e515","MULTIPROPOSAL_DOMAIN_SEPARATOR()":"abe93878","MULTIPROPOSAL_TYPEHASH()":"d06a0d82","PROPOSAL_TYPEHASH()":"853b94a0","VERSION()":"ffa1ad74","acceptProposal(address,uint256,bytes,bytes32[],bytes)":"01e83272","config()":"79502c55","decodeProposalData(bytes)":"2d5d17fc","encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":"335376cb","getMultiproposalHash((bytes32))":"829d3770","getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":"c8d44eb2","hub()":"365a86fc","makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":"a1a20ef2","proposalsMade(bytes32)":"1da4c275","revokeNonce(uint256,uint256)":"579bfc30","revokedNonce()":"9788ad55","utilizedCredit()":"4379dbad"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_hub\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_revokedNonce\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_config\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_utilizedCredit\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"AcceptorIsProposer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"AddressMissingHubTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"CallerIsNotStatedProposer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowed\",\"type\":\"address\"}],\"name\":\"CallerNotAllowedAcceptor\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"name\":\"CallerNotLoanContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"defaultDate\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"current\",\"type\":\"uint32\"}],\"name\":\"DefaultDateInPast\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"Expired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"current\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"proposed\",\"type\":\"bytes32\"}],\"name\":\"InvalidCollateralStateFingerprint\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"}],\"name\":\"InvalidRefinancingLoanId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"digest\",\"type\":\"bytes32\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MissingStateFingerprintComputer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceNotUsable\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"ProposalMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTIPROPOSAL_DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTIPROPOSAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROPOSAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"proposalData\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"proposalInclusionProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"acceptProposal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"lender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"duration\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"credit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"bytes32\",\"name\":\"lenderSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"borrowerSpecHash\",\"type\":\"bytes32\"}],\"internalType\":\"struct PWNSimpleLoan.Terms\",\"name\":\"loanTerms\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"internalType\":\"contract PWNConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"proposalData\",\"type\":\"bytes\"}],\"name\":\"decodeProposalData\",\"outputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"encodeProposalData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"multiproposalMerkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"struct PWNSimpleLoanProposal.Multiproposal\",\"name\":\"multiproposal\",\"type\":\"tuple\"}],\"name\":\"getMultiproposalHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"getProposalHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hub\",\"outputs\":[{\"internalType\":\"contract PWNHub\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"collateralCategory\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"collateralAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"checkCollateralStateFingerprint\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"collateralStateFingerprint\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"creditAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCreditLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"utilizedCreditId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"durationOrDate\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"allowedAcceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"proposerSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"isOffer\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoanSimpleProposal.Proposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"makeProposal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"proposalsMade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"revokeNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"revokedNonce\",\"outputs\":[{\"internalType\":\"contract PWNRevokedNonce\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"utilizedCredit\",\"outputs\":[{\"internalType\":\"contract PWNUtilizedCredit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"InvalidSignature(address,bytes32)\":[{\"details\":\"Thrown when signature is invalid.\"}],\"InvalidSignatureLength(uint256)\":[{\"details\":\"Thrown when signature length is not 64 nor 65 bytes.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"details\":\"Maybe nonce is revoked or not in the current nonce space.\"}]},\"kind\":\"dev\",\"methods\":{\"acceptProposal(address,uint256,bytes,bytes32[],bytes)\":{\"details\":\"Function can be called only by a loan contract with appropriate PWN Hub tag.\",\"params\":{\"acceptor\":\"Address of a proposal acceptor.\",\"proposalData\":\"Encoded proposal data with signature.\",\"proposalInclusionProof\":\"Multiproposal inclusion proof. Empty if single proposal.\",\"refinancingLoanId\":\"Id of a loan to be refinanced. 0 if creating a new loan.\"},\"returns\":{\"loanTerms\":\"Loan terms.\",\"proposalHash\":\"Proposal hash.\"}},\"decodeProposalData(bytes)\":{\"params\":{\"proposalData\":\"Encoded proposal data.\"},\"returns\":{\"_0\":\"Decoded proposal struct.\"}},\"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"params\":{\"proposal\":\"Proposal struct to be encoded.\"},\"returns\":{\"_0\":\"Encoded proposal data.\"}},\"getMultiproposalHash((bytes32))\":{\"params\":{\"multiproposal\":\"Multiproposal struct.\"},\"returns\":{\"_0\":\"Multiproposal hash.\"}},\"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"params\":{\"proposal\":\"Proposal struct to be hashed.\"},\"returns\":{\"_0\":\"Proposal struct hash.\"}},\"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"details\":\"Function will mark a proposal hash as proposed.\",\"params\":{\"proposal\":\"Proposal struct containing all needed proposal data.\"},\"returns\":{\"proposalHash\":\"Proposal hash.\"}},\"revokeNonce(uint256,uint256)\":{\"params\":{\"nonce\":\"Proposal nonce to be revoked.\",\"nonceSpace\":\"Nonce space of a proposal nonce to be revoked.\"}}},\"stateVariables\":{\"PROPOSAL_TYPEHASH\":{\"details\":\"EIP-712 simple proposal struct type hash.\"}},\"title\":\"PWN Simple Loan Simple Proposal\",\"version\":1},\"userdoc\":{\"errors\":{\"AcceptorIsProposer(address)\":[{\"notice\":\"Thrown when proposal acceptor and proposer are the same.\"}],\"AddressMissingHubTag(address,bytes32)\":[{\"notice\":\"Thrown when an address is missing a PWN Hub tag.\"}],\"CallerIsNotStatedProposer(address)\":[{\"notice\":\"Thrown when a caller is not a stated proposer.\"}],\"CallerNotAllowedAcceptor(address,address)\":[{\"notice\":\"Thrown when caller is not allowed to accept a proposal.\"}],\"CallerNotLoanContract(address,address)\":[{\"notice\":\"Thrown when a caller is missing a required hub tag.\"}],\"DefaultDateInPast(uint32,uint32)\":[{\"notice\":\"Thrown when a default date is in the past.\"}],\"Expired(uint256,uint256)\":[{\"notice\":\"Thrown when a proposal is expired.\"}],\"InvalidCollateralStateFingerprint(bytes32,bytes32)\":[{\"notice\":\"Thrown when a proposed collateral state fingerprint doesn't match the current state.\"}],\"InvalidRefinancingLoanId(uint256)\":[{\"notice\":\"Thrown when provided refinance loan id cannot be used.\"}],\"MissingStateFingerprintComputer()\":[{\"notice\":\"Thrown when a state fingerprint computer is not registered.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"notice\":\"Thrown when nonce is currently not usable.\"}]},\"events\":{\"ProposalMade(bytes32,address,(uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Emitted when a proposal is made via an on-chain transaction.\"}},\"kind\":\"user\",\"methods\":{\"acceptProposal(address,uint256,bytes,bytes32[],bytes)\":{\"notice\":\"Accept a proposal and create new loan terms.\"},\"decodeProposalData(bytes)\":{\"notice\":\"Decode proposal data.\"},\"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Encode proposal data.\"},\"getMultiproposalHash((bytes32))\":{\"notice\":\"Get a multiproposal hash according to EIP-712.\"},\"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Get an proposal hash according to EIP-712\"},\"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))\":{\"notice\":\"Make an on-chain proposal.\"},\"revokeNonce(uint256,uint256)\":{\"notice\":\"Helper function for revoking a proposal nonce on behalf of a caller.\"}},\"notice\":\"Contract for creating and accepting simple loan proposals.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol\":\"PWNSimpleLoanSimpleProposal\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/MultiToken/src/MultiToken.sol\":{\"keccak256\":\"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18\",\"dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh\"]},\"lib/MultiToken/src/interfaces/ICryptoKitties.sol\":{\"keccak256\":\"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa\",\"dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze\"]},\"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol\":{\"keccak256\":\"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1\",\"dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\":{\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16\",\"dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c\",\"dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e\",\"dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b\",\"dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95\",\"dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol\":{\"keccak256\":\"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b\",\"dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45\",\"dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol\":{\"keccak256\":\"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8\",\"dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6\"]},\"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol\":{\"keccak256\":\"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf\",\"dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec\",\"dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005\",\"dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4\",\"dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol\":{\"keccak256\":\"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04\",\"dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd\",\"dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278\",\"dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"src/PWNErrors.sol\":{\"keccak256\":\"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f\",\"dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc\"]},\"src/config/PWNConfig.sol\":{\"keccak256\":\"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7\",\"dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]},\"src/hub/PWNHubTags.sol\":{\"keccak256\":\"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8\",\"dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ\"]},\"src/interfaces/IERC5646.sol\":{\"keccak256\":\"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180\",\"dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki\"]},\"src/interfaces/IPWNLoanMetadataProvider.sol\":{\"keccak256\":\"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6\",\"dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK\"]},\"src/interfaces/IPoolAdapter.sol\":{\"keccak256\":\"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b\",\"dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T\"]},\"src/interfaces/IStateFingerpringComputer.sol\":{\"keccak256\":\"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c\",\"dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct\"]},\"src/loan/lib/PWNFeeCalculator.sol\":{\"keccak256\":\"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5\",\"dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq\"]},\"src/loan/lib/PWNSignatureChecker.sol\":{\"keccak256\":\"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1\",\"dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM\"]},\"src/loan/terms/simple/loan/PWNSimpleLoan.sol\":{\"keccak256\":\"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129\",\"dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP\"]},\"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol\":{\"keccak256\":\"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13\",\"dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP\"]},\"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol\":{\"keccak256\":\"0xbd5115ed81ecc5987dd6d21c32185269579eb2dc920572b5b725b511d6e6047c\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4bdf73983e3c1dc63d99d4aea19ebc22c533071980c9cf2741e64fea73cbea78\",\"dweb:/ipfs/QmPBiKj9qaQt4Fwbj9hG1qmh6hsMLCpXHNkRTvc5yutp3N\"]},\"src/loan/token/PWNLOAN.sol\":{\"keccak256\":\"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219\",\"dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo\"]},\"src/loan/vault/PWNVault.sol\":{\"keccak256\":\"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b\",\"dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq\"]},\"src/nonce/PWNRevokedNonce.sol\":{\"keccak256\":\"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f\",\"dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS\"]},\"src/utilized-credit/PWNUtilizedCredit.sol\":{\"keccak256\":\"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441\",\"dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"address","name":"_revokedNonce","type":"address"},{"internalType":"address","name":"_config","type":"address"},{"internalType":"address","name":"_utilizedCredit","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"type":"error","name":"AcceptorIsProposer"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"}],"type":"error","name":"AddressMissingHubTag"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"type":"error","name":"CallerIsNotStatedProposer"},{"inputs":[{"internalType":"address","name":"current","type":"address"},{"internalType":"address","name":"allowed","type":"address"}],"type":"error","name":"CallerNotAllowedAcceptor"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"loanContract","type":"address"}],"type":"error","name":"CallerNotLoanContract"},{"inputs":[{"internalType":"uint32","name":"defaultDate","type":"uint32"},{"internalType":"uint32","name":"current","type":"uint32"}],"type":"error","name":"DefaultDateInPast"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"type":"error","name":"Expired"},{"inputs":[{"internalType":"bytes32","name":"current","type":"bytes32"},{"internalType":"bytes32","name":"proposed","type":"bytes32"}],"type":"error","name":"InvalidCollateralStateFingerprint"},{"inputs":[{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"}],"type":"error","name":"InvalidRefinancingLoanId"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"digest","type":"bytes32"}],"type":"error","name":"InvalidSignature"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"type":"error","name":"InvalidSignatureLength"},{"inputs":[],"type":"error","name":"MissingStateFingerprintComputer"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"type":"error","name":"NonceNotUsable"},{"inputs":[{"internalType":"bytes32","name":"proposalHash","type":"bytes32","indexed":true},{"internalType":"address","name":"proposer","type":"address","indexed":true},{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}],"indexed":false}],"type":"event","name":"ProposalMade","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MULTIPROPOSAL_DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MULTIPROPOSAL_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"PROPOSAL_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"address","name":"acceptor","type":"address"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"bytes","name":"proposalData","type":"bytes"},{"internalType":"bytes32[]","name":"proposalInclusionProof","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"acceptProposal","outputs":[{"internalType":"bytes32","name":"proposalHash","type":"bytes32"},{"internalType":"struct PWNSimpleLoan.Terms","name":"loanTerms","type":"tuple","components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint32","name":"duration","type":"uint32"},{"internalType":"struct MultiToken.Asset","name":"collateral","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"struct MultiToken.Asset","name":"credit","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"bytes32","name":"lenderSpecHash","type":"bytes32"},{"internalType":"bytes32","name":"borrowerSpecHash","type":"bytes32"}]}]},{"inputs":[],"stateMutability":"view","type":"function","name":"config","outputs":[{"internalType":"contract PWNConfig","name":"","type":"address"}]},{"inputs":[{"internalType":"bytes","name":"proposalData","type":"bytes"}],"stateMutability":"pure","type":"function","name":"decodeProposalData","outputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}]},{"inputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}],"stateMutability":"pure","type":"function","name":"encodeProposalData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}]},{"inputs":[{"internalType":"struct PWNSimpleLoanProposal.Multiproposal","name":"multiproposal","type":"tuple","components":[{"internalType":"bytes32","name":"multiproposalMerkleRoot","type":"bytes32"}]}],"stateMutability":"view","type":"function","name":"getMultiproposalHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}],"stateMutability":"view","type":"function","name":"getProposalHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"hub","outputs":[{"internalType":"contract PWNHub","name":"","type":"address"}]},{"inputs":[{"internalType":"struct PWNSimpleLoanSimpleProposal.Proposal","name":"proposal","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"collateralCategory","type":"uint8"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"checkCollateralStateFingerprint","type":"bool"},{"internalType":"bytes32","name":"collateralStateFingerprint","type":"bytes32"},{"internalType":"address","name":"creditAddress","type":"address"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"uint256","name":"availableCreditLimit","type":"uint256"},{"internalType":"bytes32","name":"utilizedCreditId","type":"bytes32"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint32","name":"durationOrDate","type":"uint32"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"allowedAcceptor","type":"address"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bytes32","name":"proposerSpecHash","type":"bytes32"},{"internalType":"bool","name":"isOffer","type":"bool"},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"loanContract","type":"address"}]}],"stateMutability":"nonpayable","type":"function","name":"makeProposal","outputs":[{"internalType":"bytes32","name":"proposalHash","type":"bytes32"}]},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","name":"proposalsMade","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"revokeNonce"},{"inputs":[],"stateMutability":"view","type":"function","name":"revokedNonce","outputs":[{"internalType":"contract PWNRevokedNonce","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"utilizedCredit","outputs":[{"internalType":"contract PWNUtilizedCredit","name":"","type":"address"}]}],"devdoc":{"kind":"dev","methods":{"acceptProposal(address,uint256,bytes,bytes32[],bytes)":{"details":"Function can be called only by a loan contract with appropriate PWN Hub tag.","params":{"acceptor":"Address of a proposal acceptor.","proposalData":"Encoded proposal data with signature.","proposalInclusionProof":"Multiproposal inclusion proof. Empty if single proposal.","refinancingLoanId":"Id of a loan to be refinanced. 0 if creating a new loan."},"returns":{"loanTerms":"Loan terms.","proposalHash":"Proposal hash."}},"decodeProposalData(bytes)":{"params":{"proposalData":"Encoded proposal data."},"returns":{"_0":"Decoded proposal struct."}},"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"params":{"proposal":"Proposal struct to be encoded."},"returns":{"_0":"Encoded proposal data."}},"getMultiproposalHash((bytes32))":{"params":{"multiproposal":"Multiproposal struct."},"returns":{"_0":"Multiproposal hash."}},"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"params":{"proposal":"Proposal struct to be hashed."},"returns":{"_0":"Proposal struct hash."}},"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"details":"Function will mark a proposal hash as proposed.","params":{"proposal":"Proposal struct containing all needed proposal data."},"returns":{"proposalHash":"Proposal hash."}},"revokeNonce(uint256,uint256)":{"params":{"nonce":"Proposal nonce to be revoked.","nonceSpace":"Nonce space of a proposal nonce to be revoked."}}},"version":1},"userdoc":{"kind":"user","methods":{"acceptProposal(address,uint256,bytes,bytes32[],bytes)":{"notice":"Accept a proposal and create new loan terms."},"decodeProposalData(bytes)":{"notice":"Decode proposal data."},"encodeProposalData((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"notice":"Encode proposal data."},"getMultiproposalHash((bytes32))":{"notice":"Get a multiproposal hash according to EIP-712."},"getProposalHash((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"notice":"Get an proposal hash according to EIP-712"},"makeProposal((uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address))":{"notice":"Make an on-chain proposal."},"revokeNonce(uint256,uint256)":{"notice":"Helper function for revoking a proposal nonce on behalf of a caller."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol":"PWNSimpleLoanSimpleProposal"},"evmVersion":"london","libraries":{}},"sources":{"lib/MultiToken/src/MultiToken.sol":{"keccak256":"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da","urls":["bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18","dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh"],"license":"MIT"},"lib/MultiToken/src/interfaces/ICryptoKitties.sol":{"keccak256":"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706","urls":["bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa","dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze"],"license":"MIT"},"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol":{"keccak256":"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a","urls":["bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1","dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol":{"keccak256":"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510","urls":["bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16","dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"keccak256":"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e","urls":["bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c","dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794","urls":["bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e","dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"keccak256":"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422","urls":["bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b","dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef","urls":["bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95","dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol":{"keccak256":"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2","urls":["bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b","dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45","urls":["bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45","dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol":{"keccak256":"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c","urls":["bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8","dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol":{"keccak256":"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582","urls":["bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf","dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol":{"keccak256":"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b","urls":["bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec","dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol":{"keccak256":"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac","urls":["bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04","dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol":{"keccak256":"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5","urls":["bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd","dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad","urls":["bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278","dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"src/PWNErrors.sol":{"keccak256":"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24","urls":["bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f","dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc"],"license":"GPL-3.0-only"},"src/config/PWNConfig.sol":{"keccak256":"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f","urls":["bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7","dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz"],"license":"GPL-3.0-only"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"},"src/hub/PWNHubTags.sol":{"keccak256":"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a","urls":["bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8","dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ"],"license":"GPL-3.0-only"},"src/interfaces/IERC5646.sol":{"keccak256":"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e","urls":["bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180","dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki"],"license":"GPL-3.0-only"},"src/interfaces/IPWNLoanMetadataProvider.sol":{"keccak256":"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8","urls":["bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6","dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK"],"license":"GPL-3.0-only"},"src/interfaces/IPoolAdapter.sol":{"keccak256":"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89","urls":["bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b","dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T"],"license":"GPL-3.0-only"},"src/interfaces/IStateFingerpringComputer.sol":{"keccak256":"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2","urls":["bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c","dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct"],"license":"GPL-3.0-only"},"src/loan/lib/PWNFeeCalculator.sol":{"keccak256":"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf","urls":["bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5","dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq"],"license":"GPL-3.0-only"},"src/loan/lib/PWNSignatureChecker.sol":{"keccak256":"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd","urls":["bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1","dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM"],"license":"GPL-3.0-only"},"src/loan/terms/simple/loan/PWNSimpleLoan.sol":{"keccak256":"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80","urls":["bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129","dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP"],"license":"GPL-3.0-only"},"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol":{"keccak256":"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96","urls":["bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13","dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP"],"license":"GPL-3.0-only"},"src/loan/terms/simple/proposal/PWNSimpleLoanSimpleProposal.sol":{"keccak256":"0xbd5115ed81ecc5987dd6d21c32185269579eb2dc920572b5b725b511d6e6047c","urls":["bzz-raw://4bdf73983e3c1dc63d99d4aea19ebc22c533071980c9cf2741e64fea73cbea78","dweb:/ipfs/QmPBiKj9qaQt4Fwbj9hG1qmh6hsMLCpXHNkRTvc5yutp3N"],"license":"GPL-3.0-only"},"src/loan/token/PWNLOAN.sol":{"keccak256":"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb","urls":["bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219","dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo"],"license":"GPL-3.0-only"},"src/loan/vault/PWNVault.sol":{"keccak256":"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c","urls":["bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b","dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq"],"license":"GPL-3.0-only"},"src/nonce/PWNRevokedNonce.sol":{"keccak256":"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e","urls":["bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f","dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS"],"license":"GPL-3.0-only"},"src/utilized-credit/PWNUtilizedCredit.sol":{"keccak256":"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3","urls":["bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441","dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC"],"license":"GPL-3.0-only"}},"version":1},"id":99} \ No newline at end of file diff --git a/packages/subgraph/config/mainnet.json b/packages/subgraph/config/mainnet.json new file mode 100644 index 00000000..ce20304b --- /dev/null +++ b/packages/subgraph/config/mainnet.json @@ -0,0 +1,5 @@ +{ + "network": "mainnet", + "SimpleLoanAddress": "0x719A69d0dc67bd3Aa7648D4694081B3c87952797", + "SimpleLoanStartBlock": 21628749 + } \ No newline at end of file diff --git a/packages/subgraph/config/sepolia.json b/packages/subgraph/config/sepolia.json new file mode 100644 index 00000000..1d54d07c --- /dev/null +++ b/packages/subgraph/config/sepolia.json @@ -0,0 +1,5 @@ +{ + "network": "sepolia", + "SimpleLoanAddress": "0x719A69d0dc67bd3Aa7648D4694081B3c87952797", + "SimpleLoanStartBlock": 7298850 + } \ No newline at end of file diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index be6bc599..160601fc 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -15,6 +15,8 @@ } }, "scripts": { + "prepare:mainnet": "mustache config/mainnet.json subgraph.template.yaml > subgraph.yaml", + "prepare:sepolia": "mustache config/sepolia.json subgraph.template.yaml > subgraph.yaml", "codegen": "nx exec -- graph codegen", "build": "nx exec -- graph build", "deploy": "nx exec -- graph deploy --node https://api.studio.thegraph.com/deploy/ pwn-test-proposals", @@ -23,8 +25,9 @@ "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals" }, "dependencies": { - "@graphprotocol/graph-cli": "0.97.0", - "@graphprotocol/graph-ts": "0.37.0" + "@graphprotocol/graph-cli": "0.97.1", + "@graphprotocol/graph-ts": "0.38.1", + "mustache": "^3.1.0" }, "files": ["dist", "!**/*.tsbuildinfo"] } diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 2d5ddadd..eb4b837c 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -1,97 +1,52 @@ -# Define the structure of your queryable data - type Account @entity(immutable: true) { - id: Bytes! # Ethereum address - proposalsAsBorrower: [Proposal!]! @derivedFrom(field: "borrower") - proposalsAsLender: [Proposal!]! @derivedFrom(field: "lender") - loansAsBorrower: [Loan!]! @derivedFrom(field: "borrower") - loansAsLender: [Loan!]! @derivedFrom(field: "lender") - erc20Balances: [ERC20Balance!]! @derivedFrom(field: "account") - nftBalances: [NFTBalance!]! @derivedFrom(field: "owner") + id: Bytes! # Ethereum address + loansAsBorrower: [Loan!]! @derivedFrom(field: "borrower") + loansAsLender: [Loan!]! @derivedFrom(field: "lender") } -type Proposal @entity(immutable: true) { - id: ID! # Combination of chainId and proposalId from contract - proposalId: BigInt! # Proposal ID from contract event - chainId: BigInt! # Chain ID where proposal exists - contractAddress: Bytes! # Address of the specific proposal contract (e.g., SimpleLoanSimpleProposal) - borrower: Account! # Borrower address - lender: Account # Lender address (null until accepted) - - collateralType: String! # ERC20, ERC721, ERC1155 - collateralAddress: Bytes! - collateralTokenId: BigInt # Null for ERC20 - collateralAmount: BigDecimal # Amount for ERC20 +type Asset @entity(immutable: true) { + id: String! # Combination of chainId and loanId from contract - loanAmount: BigDecimal! - loanCurrency: Bytes! # Address of the loan currency (ERC20 token) - interestRate: BigDecimal # Or other interest/fee model details - duration: BigInt! # Loan duration in seconds + category: Int! + assetAddress: Bytes! + assetId: BigInt! + amount: BigDecimal! +} - status: String! # PENDING, ACCEPTED, REPAID, LIQUIDATED, CANCELED - metadataURI: String # IPFS CID for richer proposal metadata +type Loan @entity(immutable: false) { + # Combination of chainId and loanId from contract + id: String! - createdAtTimestamp: BigInt! - createdAtBlockNumber: BigInt! - transactionHash: Bytes! + # Loan ID from contract event + loanId: BigInt! + + # Proposal contract address + proposalContract: Bytes! - loan: Loan # Link to the resulting loan if accepted -} + # Loan contract address + contractAddress: Bytes! -type Loan @entity(immutable: false) { - id: ID! # Combination of chainId and loanId from contract - loanId: BigInt! # Loan ID from contract event - chainId: BigInt! - contractAddress: Bytes! # Address of the specific loan contract (e.g., SimpleLoan) - proposal: Proposal! # Link back to the proposal + # Hash of accepted proposal + proposalHash: Bytes! borrower: Account! lender: Account! - startDate: BigInt! - dueDate: BigInt! - repaymentAmount: BigDecimal! # Total amount to repay (principal + interest/fees) + createdAt: BigInt! - status: String! # ACTIVE, REPAID, LIQUIDATED, DEFAULTED + # Terms - repaidAmount: BigDecimal # Amount repaid so far - repaidTimestamp: BigInt - liquidatedTimestamp: BigInt + # Duration + duration: BigInt! - # Consider adding fields related to collateral state during the loan -} + # Collateral + collateral: Asset! -# --- Supporting Entities --- + # Credit + credit: Asset! -type ERC20Balance @entity(immutable: true) { - id: ID! # Combination of account address and token address - account: Account! - tokenAddress: Bytes! - amount: BigDecimal! - lastUpdatedBlock: BigInt! -} + # Status might be ACTIVE, REPAID, DEFAULTED, CLAIMED + status: String! -type NFTBalance @entity(immutable: true) { - id: ID! # Combination of owner address, contract address, and token ID - owner: Account! - contractAddress: Bytes! - tokenId: BigInt! - tokenURI: String # Fetched from contract - metadata: NFTMetadata # Link to potentially fetched metadata - lastUpdatedBlock: BigInt! + extra: Bytes! } - -type NFTMetadata @entity(immutable: true) { - id: ID! # Usually the tokenURI or CID - name: String - description: String - image: String - attributes: [NFTAttribute!] -} - -type NFTAttribute @entity(immutable: true) { - id: ID! - metadata: NFTMetadata! - trait_type: String! - value: String! -} \ No newline at end of file diff --git a/packages/subgraph/src/loan-mapping.ts b/packages/subgraph/src/loan-mapping.ts index e936e52f..c26a219e 100644 --- a/packages/subgraph/src/loan-mapping.ts +++ b/packages/subgraph/src/loan-mapping.ts @@ -1,8 +1,6 @@ -// Placeholder for SimpleLoan contract event handlers -import { BigDecimal, BigInt as BigIntType, } from "@graphprotocol/graph-ts"; -import { Address } from "@graphprotocol/graph-ts"; -import { LOANClaimed, LOANCreated, LOANPaidBack, } from "../generated/PWN_SimpleLoan/SimpleLoan"; // Path to generated code -import { Account, Loan, Proposal } from "../generated/schema"; +import { Address, BigDecimal } from "@graphprotocol/graph-ts"; +import { LOANClaimed, LOANCreated, LOANPaidBack, LOANCreatedTermsCollateralStruct, LOANCreatedTermsCreditStruct } from "../generated/PWN_SimpleLoan/SimpleLoan"; // Path to generated code +import { Account, Asset, Loan } from "../generated/schema"; // Helper to get or create an Account entity function getOrCreateAccount(address: Address): Account { @@ -14,41 +12,61 @@ function getOrCreateAccount(address: Address): Account { return account; } -function findProposalById(proposalId: BigIntType): Proposal { - let proposal = Proposal.load(proposalId.toString()); - if (proposal == null) { - proposal = new Proposal(proposalId.toString()); - proposal.save(); +function getOrCreateCollateralAsset(asset: LOANCreatedTermsCollateralStruct): Asset { + const assetEntityId = `${asset.assetAddress.toHex()}-${asset.id.toString()}`; + let collateralAsset = Asset.load(assetEntityId); + if (collateralAsset == null) { + collateralAsset = new Asset(assetEntityId); + collateralAsset.category = asset.category; + collateralAsset.assetAddress = asset.assetAddress; + collateralAsset.assetId = asset.id; + collateralAsset.amount = new BigDecimal(asset.amount); + collateralAsset.save(); } - return proposal; + return collateralAsset; } -export function handleLOANCreated(event: LOANCreated): void { - // TODO: Implement mapping logic based on LOANCreated event parameters - // Need to parse the complex nested tuple for proposal details +function getOrCreateCreditAsset(asset: LOANCreatedTermsCreditStruct): Asset { + const assetEntityId = `${asset.assetAddress.toHex()}-${asset.id.toString()}`; + let creditAsset = Asset.load(assetEntityId); + if (creditAsset == null) { + creditAsset = new Asset(assetEntityId); + creditAsset.category = asset.category; + creditAsset.assetAddress = asset.assetAddress; + creditAsset.assetId = asset.id; + creditAsset.amount = new BigDecimal(asset.amount); + creditAsset.save(); + } + return creditAsset; +} +export function handleLOANCreated(event: LOANCreated): void { const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; const loan = new Loan(loanEntityId); + loan.loanId = event.params.loanId; - loan.chainId = BigIntType.fromI32(1); // TODO: Hardcoded Mainnet + loan.proposalHash = event.params.proposalHash; loan.contractAddress = event.address; + loan.proposalContract = event.params.proposalContract; + + const terms = event.params.terms; - // Example of accessing nested data (needs verification based on ABI) - const proposalData = event.params.terms; - loan.borrower = getOrCreateAccount(proposalData.borrower).id; - loan.lender = getOrCreateAccount(proposalData.lender).id; // Lender should be set here - loan.proposal = event.params.proposalHash.toHex(); // Need a way to find the original proposal + loan.borrower = getOrCreateAccount(terms.borrower).id; + loan.lender = getOrCreateAccount(terms.lender).id; - loan.startDate = event.block.timestamp; - loan.dueDate = event.block.timestamp.plus(proposalData.duration); // Calculate due date as start date + duration - loan.repaymentAmount = BigDecimal.fromString( - proposalData.accruingInterestAPR.toString(), - ).times(BigDecimal.fromString(proposalData.credit.amount.toString())); // Need to verify param names + loan.createdAt = event.block.timestamp; + + // terms setting + loan.duration = terms.duration; + loan.collateral = getOrCreateCollateralAsset(terms.collateral).id; + loan.credit = getOrCreateCreditAsset(terms.credit).id; loan.status = "ACTIVE"; + + loan.extra = event.params.extra; + loan.save(); - // TODO: Update the linked Proposal entity status } export function handleLOANPaidBack(event: LOANPaidBack): void { @@ -57,8 +75,6 @@ export function handleLOANPaidBack(event: LOANPaidBack): void { if (!loan) return; loan.status = "REPAID"; - loan.repaidTimestamp = event.block.timestamp; - // loan.repaidAmount = ??? // Need event param or contract read loan.save(); // TODO: Update the linked Proposal entity status @@ -69,16 +85,9 @@ export function handleLOANClaimed(event: LOANClaimed): void { const loan = Loan.load(loanEntityId); if (!loan) return; - // Logic to determine if this is a liquidation or regular claim - // Could check event.block.timestamp against loan.dueDate - // Could check event.params.liquidated flag if (event.params.defaulted) { loan.status = "DEFAULTED"; - loan.liquidatedTimestamp = event.block.timestamp; - } else { - // Handle regular claim if necessary (maybe update status?) } - loan.save(); - // TODO: Update the linked Proposal entity status accordingly + loan.save(); } diff --git a/packages/subgraph/src/proposal-mapping.ts b/packages/subgraph/src/proposal-mapping.ts deleted file mode 100644 index 91dc2eaa..00000000 --- a/packages/subgraph/src/proposal-mapping.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Placeholder for SimpleLoanSimpleProposal contract event handlers -import { type Address, BigInt as BigIntType } from "@graphprotocol/graph-ts"; -import type { ProposalMade } from "../generated/PWN_SimpleLoanSimpleProposal/SimpleLoanSimpleProposal"; -import { Account, Proposal } from "../generated/schema"; - -// Helper to get or create an Account entity -function getOrCreateAccount(address: Address): Account { - let account = Account.load(address); - if (account == null) { - account = new Account(address); - account.save(); - } - return account; -} - -export function handleProposalMade(event: ProposalMade): void { - const proposalEntityId = event.params.proposalHash.toHex(); - const proposal = new Proposal(proposalEntityId); - - proposal.chainId = BigIntType.fromI32(1); // TODO: Hardcoded Mainnet - proposal.contractAddress = event.address; - proposal.borrower = getOrCreateAccount(event.params.proposer).id; - - proposal.collateralType = - proposal.collateralType === "0" - ? "ERC20" - : proposal.collateralType === "1" - ? "ERC721" - : "ERC1155"; - - proposal.status = "PENDING"; - proposal.createdAtTimestamp = event.block.timestamp; - proposal.createdAtBlockNumber = event.block.number; - proposal.transactionHash = event.transaction.hash; - - proposal.save(); -} diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml new file mode 100644 index 00000000..e92b4d95 --- /dev/null +++ b/packages/subgraph/subgraph.template.yaml @@ -0,0 +1,28 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +dataSources: + # Simple Loan Contract + - kind: ethereum/contract + name: PWN_SimpleLoan + network: {{network}} + source: + address: "{{SimpleLoanAddress}}" + abi: SimpleLoan + startBlock: {{SimpleLoanStartBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: [ Loan, Account ] + abis: + - name: SimpleLoan + file: ./abis/SimpleLoan.json + eventHandlers: + - event: LOANCreated(indexed uint256,indexed bytes32,indexed address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) + handler: handleLOANCreated + - event: LOANPaidBack(indexed uint256) + handler: handleLOANPaidBack + - event: LOANClaimed(indexed uint256,indexed bool) + handler: handleLOANClaimed + file: ./src/loan-mapping.ts diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index c3dbb864..bda233ac 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -5,26 +5,24 @@ dataSources: # Simple Loan Contract - kind: ethereum/contract name: PWN_SimpleLoan - network: base + network: sepolia source: - address: "0x719A69d0dc67bd3Aa7648D4694081B3c87952797" # Mainnet SimpleLoan from v1.3.json + address: "0x719A69d0dc67bd3Aa7648D4694081B3c87952797" abi: SimpleLoan - startBlock: 25032814 # TODO: Find actual deployment block + startBlock: 7298850 mapping: kind: ethereum/events apiVersion: 0.0.7 language: wasm/assemblyscript - entities: [ Loan, Account, Proposal ] + entities: [ Loan, Account ] abis: - name: SimpleLoan file: ./abis/SimpleLoan.json - - name: SimpleLoanSimpleProposal # Needed for context? - file: ./abis/SimpleLoanSimpleProposal.json eventHandlers: - event: LOANCreated(indexed uint256,indexed bytes32,indexed address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) - handler: handleLOANCreated # Use this instead of LoanStarted + handler: handleLOANCreated - event: LOANPaidBack(indexed uint256) - handler: handleLOANPaidBack # Use this instead of LoanRepaid + handler: handleLOANPaidBack - event: LOANClaimed(indexed uint256,indexed bool) - handler: handleLOANClaimed # Potential signal for liquidation/claim + handler: handleLOANClaimed file: ./src/loan-mapping.ts From 0cadc3a792badeded7c47709a175cbc1ddb704bd Mon Sep 17 00:00:00 2001 From: microHoffman Date: Tue, 10 Jun 2025 12:55:59 +0200 Subject: [PATCH 03/13] feat: continue with subgraph --- bun.lockb | Bin 1362872 -> 1362960 bytes packages/subgraph/.gitignore | 3 + packages/subgraph/README.md | 7 + packages/subgraph/TIME_BASED_DEFAULTS.md | 203 +++ .../subgraph/abis/ChainlinkFeedRegistry.json | 530 ++++++++ packages/subgraph/abis/Config.json | 358 +++++- packages/subgraph/abis/Hub.json | 199 ++- packages/subgraph/abis/LoanToken.json | 293 ++++- .../abis/MultiTokenCategoryRegistry.json | 154 +++ packages/subgraph/abis/SimpleLoan.json | 1101 ++++++++++++++++- .../SimpleLoanElasticChainlinkProposal.json | 1080 ++++++++++++++++ .../abis/SimpleLoanElasticProposal.json | 937 ++++++++++++++ .../subgraph/abis/SimpleLoanListProposal.json | 921 ++++++++++++++ .../abis/SimpleLoanSimpleProposal.json | 882 +++++++++++++ packages/subgraph/config/mainnet.json | 46 +- packages/subgraph/config/sepolia.json | 46 +- packages/subgraph/schema.graphql | 513 +++++++- .../subgraph/src/chainlink-feed-registry.ts | 97 ++ packages/subgraph/src/config.ts | 170 +++ packages/subgraph/src/contract.ts | 37 - packages/subgraph/src/hub.ts | 57 + packages/subgraph/src/loan-mapping.ts | 67 +- packages/subgraph/src/loan-token.ts | 87 ++ .../src/multi-token-category-registry.ts | 83 ++ .../simple-loan-elastic-chainlink-proposal.ts | 48 + .../src/simple-loan-elastic-proposal.ts | 44 + .../subgraph/src/simple-loan-list-proposal.ts | 44 + .../src/simple-loan-simple-proposal.ts | 43 + packages/subgraph/src/simple-loan.ts | 215 ++++ packages/subgraph/subgraph.template.yaml | 310 ++++- packages/subgraph/subgraph.yaml | 306 ++++- .../tests/chainlink-feed-registry-utils.ts | 153 +++ .../tests/chainlink-feed-registry.test.ts | 60 + packages/subgraph/tests/config-utils.ts | 203 +++ packages/subgraph/tests/config.test.ts | 57 + packages/subgraph/tests/hub-utils.ts | 73 ++ packages/subgraph/tests/hub.test.ts | 60 + packages/subgraph/tests/loan-token-utils.ts | 118 ++ packages/subgraph/tests/loan-token.test.ts | 62 + .../multi-token-category-registry-utils.ts | 94 ++ .../multi-token-category-registry.test.ts | 58 + ...e-loan-elastic-chainlink-proposal-utils.ts | 28 + ...le-loan-elastic-chainlink-proposal.test.ts | 66 + .../simple-loan-elastic-proposal-utils.ts | 28 + .../simple-loan-elastic-proposal.test.ts | 66 + .../tests/simple-loan-list-proposal-utils.ts | 28 + .../tests/simple-loan-list-proposal.test.ts | 66 + .../simple-loan-simple-proposal-utils.ts | 28 + .../tests/simple-loan-simple-proposal.test.ts | 66 + packages/subgraph/tests/simple-loan-utils.ts | 267 ++++ packages/subgraph/tests/simple-loan.test.ts | 66 + packages/subgraph/tsconfig.json | 6 +- packages/subgraph/tsconfig.lib.json | 8 +- packages/subgraph/tsconfig.spec.json | 4 +- 54 files changed, 10465 insertions(+), 81 deletions(-) create mode 100644 packages/subgraph/README.md create mode 100644 packages/subgraph/TIME_BASED_DEFAULTS.md create mode 100644 packages/subgraph/abis/ChainlinkFeedRegistry.json create mode 100644 packages/subgraph/abis/MultiTokenCategoryRegistry.json create mode 100644 packages/subgraph/abis/SimpleLoanElasticChainlinkProposal.json create mode 100644 packages/subgraph/abis/SimpleLoanElasticProposal.json create mode 100644 packages/subgraph/abis/SimpleLoanListProposal.json create mode 100644 packages/subgraph/abis/SimpleLoanSimpleProposal.json create mode 100644 packages/subgraph/src/chainlink-feed-registry.ts create mode 100644 packages/subgraph/src/config.ts delete mode 100644 packages/subgraph/src/contract.ts create mode 100644 packages/subgraph/src/hub.ts create mode 100644 packages/subgraph/src/loan-token.ts create mode 100644 packages/subgraph/src/multi-token-category-registry.ts create mode 100644 packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts create mode 100644 packages/subgraph/src/simple-loan-elastic-proposal.ts create mode 100644 packages/subgraph/src/simple-loan-list-proposal.ts create mode 100644 packages/subgraph/src/simple-loan-simple-proposal.ts create mode 100644 packages/subgraph/src/simple-loan.ts create mode 100644 packages/subgraph/tests/chainlink-feed-registry-utils.ts create mode 100644 packages/subgraph/tests/chainlink-feed-registry.test.ts create mode 100644 packages/subgraph/tests/config-utils.ts create mode 100644 packages/subgraph/tests/config.test.ts create mode 100644 packages/subgraph/tests/hub-utils.ts create mode 100644 packages/subgraph/tests/hub.test.ts create mode 100644 packages/subgraph/tests/loan-token-utils.ts create mode 100644 packages/subgraph/tests/loan-token.test.ts create mode 100644 packages/subgraph/tests/multi-token-category-registry-utils.ts create mode 100644 packages/subgraph/tests/multi-token-category-registry.test.ts create mode 100644 packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts create mode 100644 packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts create mode 100644 packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts create mode 100644 packages/subgraph/tests/simple-loan-elastic-proposal.test.ts create mode 100644 packages/subgraph/tests/simple-loan-list-proposal-utils.ts create mode 100644 packages/subgraph/tests/simple-loan-list-proposal.test.ts create mode 100644 packages/subgraph/tests/simple-loan-simple-proposal-utils.ts create mode 100644 packages/subgraph/tests/simple-loan-simple-proposal.test.ts create mode 100644 packages/subgraph/tests/simple-loan-utils.ts create mode 100644 packages/subgraph/tests/simple-loan.test.ts diff --git a/bun.lockb b/bun.lockb index 9d0adcd465e62171d5c373bdbf725ef7759418c4..82921f137c77f1ab2b36c9fdf02305d0b8b72837 100755 GIT binary patch delta 47958 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 Jswmao`Y+xi<~9HT delta 47524 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�Mg-SS$%JUGh{1fbR-B9 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 bXP%)KC3aSBsFwr-y7r;-RmfI>{M~;6R}XaW diff --git a/packages/subgraph/.gitignore b/packages/subgraph/.gitignore index b542c60b..1373657d 100644 --- a/packages/subgraph/.gitignore +++ b/packages/subgraph/.gitignore @@ -32,3 +32,6 @@ typechain-types # Hardhat files cache + +# note: we commit subgraph.template.yaml, but the subgraph.yaml is generated +subgraph.yaml diff --git a/packages/subgraph/README.md b/packages/subgraph/README.md new file mode 100644 index 00000000..e83bbd67 --- /dev/null +++ b/packages/subgraph/README.md @@ -0,0 +1,7 @@ +# PWNDAO subgraph + +## How to build / run +1) `bun install` from root folder +2) `bunx nx codegen @pwndao/subgraph` +3) choose what network you want to build your subgraph on, and then run e.g. `bunx nx prepare:sepolia @pwndao/subgraph` +4) `bunx nx build @pwndao/subgraph` \ No newline at end of file diff --git a/packages/subgraph/TIME_BASED_DEFAULTS.md b/packages/subgraph/TIME_BASED_DEFAULTS.md new file mode 100644 index 00000000..d298ba80 --- /dev/null +++ b/packages/subgraph/TIME_BASED_DEFAULTS.md @@ -0,0 +1,203 @@ +# Handling Time-Based Loan Defaults in Subgraphs + +## Problem +Loans default after a certain duration (`createdAt + duration`), but there's no on-chain event emitted when this happens. The subgraph needs a way to mark loans as defaulted based on time calculations. + +## Solutions + +### 1. Schema-Based Approach (Recommended) + +Add a computed field to store the default deadline: + +```graphql +type Loan @entity(immutable: false) { + # ... existing fields ... + defaultDeadline: BigInt! # createdAt + duration + # ... rest of fields ... +} +``` + +**Advantages:** +- Easy to query loans by default status +- Efficient for frontend filtering +- Clear data model + +**Implementation:** +1. Add `defaultDeadline` field to schema +2. Run `npm run codegen` to regenerate types +3. Update `handleLOANCreated` to calculate and store `defaultDeadline` + +### 2. Runtime Status Checking (Current Implementation) + +Use helper functions to check loan status based on current time: + +```typescript +function isLoanDefaulted(loan: Loan, currentTimestamp: BigInt): boolean { + if (loan.status != "Active") return false; + const defaultDeadline = loan.createdAt.plus(loan.duration); + return currentTimestamp.gt(defaultDeadline); +} +``` + +**Advantages:** +- No schema changes required +- Works immediately +- Can be applied to existing loans + +**Disadvantages:** +- Requires checking on every query +- More complex GraphQL queries needed + +### 3. Event-Driven Updates + +Update loan statuses whenever any related event occurs: + +```typescript +export function handleLOANClaimed(event: LOANClaimed): void { + // ... existing logic ... + + // Always check for time-based defaults + updateLoanStatusIfDefaulted(loan, event.block.timestamp); + loan.save(); +} +``` + +### 4. Query-Time Filtering + +Use GraphQL queries that filter based on calculated values: + +```graphql +query GetDefaultedLoans($currentTime: BigInt!) { + loans( + where: { + status: "Active" + # This would need to be calculated client-side or with a custom resolver + } + ) { + id + createdAt + duration + status + } +} +``` + +## Frontend Usage Examples + +### 1. Query with Status Calculation + +```typescript +const GET_LOANS_WITH_STATUS = gql` + query GetLoans { + loans { + id + createdAt + duration + status + defaultDeadline # If using schema approach + } + } +`; + +// Client-side calculation +const loansWithCalculatedStatus = loans.map(loan => ({ + ...loan, + isDefaulted: loan.status === 'Active' && + Date.now() / 1000 > (loan.createdAt + loan.duration), + effectiveStatus: loan.status === 'Active' && + Date.now() / 1000 > (loan.createdAt + loan.duration) + ? 'Defaulted' : loan.status +})); +``` + +### 2. Filter Defaulted Loans + +```typescript +// If using defaultDeadline field +const GET_DEFAULTED_LOANS = gql` + query GetDefaultedLoans($currentTime: BigInt!) { + loans( + where: { + or: [ + { status: "Defaulted" }, + { + status: "Active", + defaultDeadline_lt: $currentTime + } + ] + } + ) { + id + status + defaultDeadline + } + } +`; +``` + +## Implementation Steps + +1. **Choose Your Approach:** + - For new projects: Use Schema-Based Approach (#1) + - For existing projects: Use Runtime Status Checking (#2) + +2. **Update Schema (if using approach #1):** + ```bash + # Add defaultDeadline field to schema.graphql + npm run codegen + ``` + +3. **Update Event Handlers:** + - Implement time-based status checking + - Update `handleLOANCreated`, `handleLOANClaimed`, etc. + +4. **Frontend Integration:** + - Update queries to handle time-based defaults + - Add client-side status calculation if needed + +## Best Practices + +1. **Consistency:** Always check for time-based defaults in all loan-related event handlers +2. **Performance:** Use schema fields for frequently queried data +3. **Accuracy:** Consider block timestamps vs real-world time +4. **Extensions:** Handle loan extensions by updating duration/defaultDeadline +5. **Testing:** Test with various time scenarios + +## Alternative Solutions + +### Custom Resolver (Advanced) +Create a custom resolver that calculates status dynamically: + +```typescript +// This would require extending the subgraph with custom logic +export function resolveLoanStatus(loan: Loan, args: any, context: any): string { + if (loan.status !== "Active") return loan.status; + + const currentTime = context.block.timestamp; + const defaultDeadline = loan.createdAt.plus(loan.duration); + + return currentTime.gt(defaultDeadline) ? "Defaulted" : "Active"; +} +``` + +### Periodic Update Job +Create a separate service that periodically updates loan statuses: + +```typescript +// External service (not in subgraph) +async function updateDefaultedLoans() { + const activeLoans = await getActiveLoans(); + const currentTime = Math.floor(Date.now() / 1000); + + for (const loan of activeLoans) { + if (currentTime > loan.createdAt + loan.duration) { + // Update loan status in subgraph or database + await markLoanAsDefaulted(loan.id); + } + } +} +``` + +## Conclusion + +The **Schema-Based Approach** with `defaultDeadline` field is recommended for most cases as it provides the best balance of performance, clarity, and functionality. The current implementation with runtime checking works well as a transitional solution. \ No newline at end of file diff --git a/packages/subgraph/abis/ChainlinkFeedRegistry.json b/packages/subgraph/abis/ChainlinkFeedRegistry.json new file mode 100644 index 00000000..55882931 --- /dev/null +++ b/packages/subgraph/abis/ChainlinkFeedRegistry.json @@ -0,0 +1,530 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "accessController", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AccessControllerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "denomination", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "latestAggregator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "previousAggregator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "nextPhaseId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "FeedConfirmed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "denomination", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposedAggregator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "currentAggregator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "FeedProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "address", "name": "aggregator", "type": "address" } + ], + "name": "confirmFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "description", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAccessController", + "outputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint256", "name": "roundId", "type": "uint256" } + ], + "name": "getAnswer", + "outputs": [ + { "internalType": "int256", "name": "answer", "type": "int256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "getCurrentPhaseId", + "outputs": [ + { "internalType": "uint16", "name": "currentPhaseId", "type": "uint16" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "getFeed", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "aggregator", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint80", "name": "roundId", "type": "uint80" } + ], + "name": "getNextRoundId", + "outputs": [ + { "internalType": "uint80", "name": "nextRoundId", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint16", "name": "phaseId", "type": "uint16" } + ], + "name": "getPhase", + "outputs": [ + { + "components": [ + { "internalType": "uint16", "name": "phaseId", "type": "uint16" }, + { + "internalType": "uint80", + "name": "startingAggregatorRoundId", + "type": "uint80" + }, + { + "internalType": "uint80", + "name": "endingAggregatorRoundId", + "type": "uint80" + } + ], + "internalType": "struct FeedRegistryInterface.Phase", + "name": "phase", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint16", "name": "phaseId", "type": "uint16" } + ], + "name": "getPhaseFeed", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "aggregator", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint16", "name": "phaseId", "type": "uint16" } + ], + "name": "getPhaseRange", + "outputs": [ + { "internalType": "uint80", "name": "startingRoundId", "type": "uint80" }, + { "internalType": "uint80", "name": "endingRoundId", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint80", "name": "roundId", "type": "uint80" } + ], + "name": "getPreviousRoundId", + "outputs": [ + { "internalType": "uint80", "name": "previousRoundId", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "getProposedFeed", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "proposedAggregator", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint80", "name": "_roundId", "type": "uint80" } + ], + "name": "getRoundData", + "outputs": [ + { "internalType": "uint80", "name": "roundId", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint80", "name": "roundId", "type": "uint80" } + ], + "name": "getRoundFeed", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "aggregator", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint256", "name": "roundId", "type": "uint256" } + ], + "name": "getTimestamp", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "aggregator", "type": "address" } + ], + "name": "isFeedEnabled", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "latestAnswer", + "outputs": [ + { "internalType": "int256", "name": "answer", "type": "int256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "latestRound", + "outputs": [ + { "internalType": "uint256", "name": "roundId", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "latestRoundData", + "outputs": [ + { "internalType": "uint80", "name": "roundId", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "latestTimestamp", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "address", "name": "aggregator", "type": "address" } + ], + "name": "proposeFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" }, + { "internalType": "uint80", "name": "roundId", "type": "uint80" } + ], + "name": "proposedGetRoundData", + "outputs": [ + { "internalType": "uint80", "name": "id", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "proposedLatestRoundData", + "outputs": [ + { "internalType": "uint80", "name": "id", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "_accessController", + "type": "address" + } + ], + "name": "setAccessController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "typeAndVersion", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "base", "type": "address" }, + { "internalType": "address", "name": "quote", "type": "address" } + ], + "name": "version", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/abis/Config.json b/packages/subgraph/abis/Config.json index 62459408..5fd650d5 100644 --- a/packages/subgraph/abis/Config.json +++ b/packages/subgraph/abis/Config.json @@ -1 +1,357 @@ -{"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"MAX_FEE","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"type":"function","name":"acceptOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"type":"function","name":"feeCollector","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getPoolAdapter","inputs":[{"name":"pool","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"contract IPoolAdapter"}],"stateMutability":"view"},{"type":"function","name":"getStateFingerprintComputer","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"contract IStateFingerpringComputer"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"_owner","type":"address","internalType":"address"},{"name":"_fee","type":"uint16","internalType":"uint16"},{"name":"_feeCollector","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"loanMetadataUri","inputs":[{"name":"loanContract","type":"address","internalType":"address"}],"outputs":[{"name":"uri","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"pendingOwner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"registerPoolAdapter","inputs":[{"name":"pool","type":"address","internalType":"address"},{"name":"adapter","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"registerStateFingerprintComputer","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"computer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setDefaultLOANMetadataUri","inputs":[{"name":"metadataUri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFee","inputs":[{"name":"_fee","type":"uint16","internalType":"uint16"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeCollector","inputs":[{"name":"_feeCollector","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setLOANMetadataUri","inputs":[{"name":"loanContract","type":"address","internalType":"address"},{"name":"metadataUri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"DefaultLOANMetadataUriUpdated","inputs":[{"name":"newUri","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"FeeCollectorUpdated","inputs":[{"name":"oldFeeCollector","type":"address","indexed":false,"internalType":"address"},{"name":"newFeeCollector","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"FeeUpdated","inputs":[{"name":"oldFee","type":"uint16","indexed":false,"internalType":"uint16"},{"name":"newFee","type":"uint16","indexed":false,"internalType":"uint16"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"LOANMetadataUriUpdated","inputs":[{"name":"loanContract","type":"address","indexed":true,"internalType":"address"},{"name":"newUri","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"InvalidComputerContract","inputs":[{"name":"computer","type":"address","internalType":"address"},{"name":"asset","type":"address","internalType":"address"}]},{"type":"error","name":"InvalidFeeValue","inputs":[{"name":"fee","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ZeroFeeCollector","inputs":[]},{"type":"error","name":"ZeroLoanContract","inputs":[]}],"bytecode":{"object":"0x608060405234801561001057600080fd5b50610019610028565b61002360006100e7565b610160565b600054610100900460ff16156100945760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b606580546001600160a01b031916905561010b8161010e602090811b6108eb17901c565b50565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610ec38061016f6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063a42dce80116100a2578063c4743ae011610071578063c4743ae01461026b578063cbf35d881461027e578063ddca3f4314610291578063e30c39781461029f578063f2fde38b146102b057600080fd5b8063a42dce80146101f7578063b20912311461020a578063bc063e1a14610236578063c415b95c1461025257600080fd5b8063715018a6116100e9578063715018a6146101b057806379ba5097146101b85780638da5cb5b146101c05780638e005553146101d1578063935bf0d7146101e457600080fd5b8063233557501461011b5780632df927ac146101445780634bbcf8de14610188578063708c0db91461019d575b600080fd5b61012e610129366004610ae1565b6102c3565b60405161013b9190610b03565b60405180910390f35b610170610152366004610ae1565b6001600160a01b039081166000908152609960205260409020541690565b6040516001600160a01b03909116815260200161013b565b61019b610196366004610bf4565b61042e565b005b61019b6101ab366004610c54565b6104c5565b61019b61063f565b61019b610653565b6033546001600160a01b0316610170565b61019b6101df366004610c97565b6106cd565b61019b6101f2366004610cb2565b6106de565b61019b610205366004610ae1565b6107bc565b610170610218366004610ae1565b6001600160a01b039081166000908152609a60205260409020541690565b61023f6103e881565b60405161ffff909116815260200161013b565b609754610170906201000090046001600160a01b031681565b61019b610279366004610ce5565b6107cd565b61019b61028c366004610cb2565b610844565b60975461023f9061ffff1681565b6065546001600160a01b0316610170565b61019b6102be366004610ae1565b61087a565b6001600160a01b03811660009081526098602052604090208054606091906102ea90610d22565b80601f016020809104026020016040519081016040528092919081815260200182805461031690610d22565b80156103635780601f1061033857610100808354040283529160200191610363565b820191906000526020600020905b81548152906001019060200180831161034657829003601f168201915b505050505090508051600003610429576000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e80546103a890610d22565b80601f01602080910402602001604051908101604052809291908181526020018280546103d490610d22565b80156104215780601f106103f657610100808354040283529160200191610421565b820191906000526020600020905b81548152906001019060200180831161040457829003601f168201915b505050505090505b919050565b61043661093d565b6001600160a01b03821661045d5760405163a9fcf0f560e01b815260040160405180910390fd5b6001600160a01b038216600090815260986020526040902061047f8282610dab565b50816001600160a01b03167f6004b71123e07b97df793497325c4438343da4eeb06cfe39475aa69d93476527826040516104b99190610b03565b60405180910390a25050565b600054610100900460ff16158080156104e55750600054600160ff909116105b806104ff5750303b1580156104ff575060005460ff166001145b6105675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801561058a576000805461ff0019166101001790555b6001600160a01b0384166105d85760405162461bcd60e51b81526020600482015260156024820152744f776e6572206973207a65726f206164647265737360581b604482015260640161055e565b6105e184610997565b6105ea826109b0565b6105f383610a45565b8015610639576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b61064761093d565b6106516000610997565b565b60655433906001600160a01b031681146106c15760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161055e565b6106ca81610997565b50565b6106d561093d565b6106ca81610a45565b6106e661093d565b6001600160a01b0381161561078e576040516261f76560e41b81526001600160a01b03838116600483015282169063061f765090602401602060405180830381865afa15801561073a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075e9190610e6b565b61078e5760405163e12aeae760e01b81526001600160a01b0380831660048301528316602482015260440161055e565b6001600160a01b03918216600090815260996020526040902080546001600160a01b03191691909216179055565b6107c461093d565b6106ca816109b0565b6107d561093d565b6000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e6108098282610dab565b507fe358eb330ebc40c9c9375742912f9c5a8ae1db2e9990a15039c889ba971e128b816040516108399190610b03565b60405180910390a150565b61084c61093d565b6001600160a01b039182166000908152609a6020526040902080546001600160a01b03191691909216179055565b61088261093d565b606580546001600160a01b0383166001600160a01b031990911681179091556108b36033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6033546001600160a01b031633146106515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055e565b606580546001600160a01b03191690556106ca816108eb565b6001600160a01b0381166109d757604051635fb3e86760e11b815260040160405180910390fd5b609780546001600160a01b038381166201000081810262010000600160b01b031985161790945560408051949093049091168084526020840191909152917f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f3891015b60405180910390a15050565b6103e861ffff82161115610a7a5760405163f6696bd560e01b815261ffff821660048201526103e8602482015260440161055e565b6097805461ffff83811661ffff1983168117909355604080519190921680825260208201939093527f2e7c4279000925b8ff0bca0e7109cbc47fc6f6c4edfb831ffe7466cf0af07fa09101610a39565b80356001600160a01b038116811461042957600080fd5b600060208284031215610af357600080fd5b610afc82610aca565b9392505050565b600060208083528351808285015260005b81811015610b3057858101830151858201604001528201610b14565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610b7857600080fd5b813567ffffffffffffffff80821115610b9357610b93610b51565b604051601f8301601f19908116603f01168101908282118183101715610bbb57610bbb610b51565b81604052838152866020858801011115610bd457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610c0757600080fd5b610c1083610aca565b9150602083013567ffffffffffffffff811115610c2c57600080fd5b610c3885828601610b67565b9150509250929050565b803561ffff8116811461042957600080fd5b600080600060608486031215610c6957600080fd5b610c7284610aca565b9250610c8060208501610c42565b9150610c8e60408501610aca565b90509250925092565b600060208284031215610ca957600080fd5b610afc82610c42565b60008060408385031215610cc557600080fd5b610cce83610aca565b9150610cdc60208401610aca565b90509250929050565b600060208284031215610cf757600080fd5b813567ffffffffffffffff811115610d0e57600080fd5b610d1a84828501610b67565b949350505050565b600181811c90821680610d3657607f821691505b602082108103610d5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610da657600081815260208120601f850160051c81016020861015610d835750805b601f850160051c820191505b81811015610da257828155600101610d8f565b5050505b505050565b815167ffffffffffffffff811115610dc557610dc5610b51565b610dd981610dd38454610d22565b84610d5c565b602080601f831160018114610e0e5760008415610df65750858301515b600019600386901b1c1916600185901b178555610da2565b600085815260208120601f198616915b82811015610e3d57888601518255948401946001909101908401610e1e565b5085821015610e5b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215610e7d57600080fd5b81518015158114610afc57600080fdfea264697066735822122050013480b7b3f1ae431e986d3a9984428851eaf65c04a2b9cba92ca8ac167a2164736f6c63430008100033","sourceMap":"497:8860:80:-:0;;;3563:205;;;;;;;;;-1:-1:-1;3699:22:80::1;:20;:22::i;:::-;3731:30;3758:1;3731:18;:30::i;:::-;497:8860:::0;;5939:280:27;6007:13;;;;;;;6006:14;5998:66;;;;-1:-1:-1;;;5998:66:27;;216:2:137;5998:66:27;;;198:21:137;255:2;235:18;;;228:30;294:34;274:18;;;267:62;-1:-1:-1;;;345:18:137;;;338:37;392:19;;5998:66:27;;;;;;;;6078:12;;6094:15;6078:12;;;:31;6074:139;;6125:12;:30;;-1:-1:-1;;6125:30:27;6140:15;6125:30;;;;;;6174:28;;564:36:137;;;6174:28:27;;552:2:137;537:18;6174:28:27;;;;;;;6074:139;5939:280::o;1798:153:25:-;1887:13;1880:20;;-1:-1:-1;;;;;;1880:20:25;;;1910:34;1935:8;1910:24;;;;;;;:34;;:::i;:::-;1798:153;:::o;2687:187:26:-;2779:6;;;-1:-1:-1;;;;;2795:17:26;;;-1:-1:-1;;;;;;2795:17:26;;;;;;;2827:40;;2779:6;;;2795:17;2779:6;;2827:40;;2760:16;;2827:40;2750:124;2687:187;:::o;422:184:137:-;497:8860:80;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063a42dce80116100a2578063c4743ae011610071578063c4743ae01461026b578063cbf35d881461027e578063ddca3f4314610291578063e30c39781461029f578063f2fde38b146102b057600080fd5b8063a42dce80146101f7578063b20912311461020a578063bc063e1a14610236578063c415b95c1461025257600080fd5b8063715018a6116100e9578063715018a6146101b057806379ba5097146101b85780638da5cb5b146101c05780638e005553146101d1578063935bf0d7146101e457600080fd5b8063233557501461011b5780632df927ac146101445780634bbcf8de14610188578063708c0db91461019d575b600080fd5b61012e610129366004610ae1565b6102c3565b60405161013b9190610b03565b60405180910390f35b610170610152366004610ae1565b6001600160a01b039081166000908152609960205260409020541690565b6040516001600160a01b03909116815260200161013b565b61019b610196366004610bf4565b61042e565b005b61019b6101ab366004610c54565b6104c5565b61019b61063f565b61019b610653565b6033546001600160a01b0316610170565b61019b6101df366004610c97565b6106cd565b61019b6101f2366004610cb2565b6106de565b61019b610205366004610ae1565b6107bc565b610170610218366004610ae1565b6001600160a01b039081166000908152609a60205260409020541690565b61023f6103e881565b60405161ffff909116815260200161013b565b609754610170906201000090046001600160a01b031681565b61019b610279366004610ce5565b6107cd565b61019b61028c366004610cb2565b610844565b60975461023f9061ffff1681565b6065546001600160a01b0316610170565b61019b6102be366004610ae1565b61087a565b6001600160a01b03811660009081526098602052604090208054606091906102ea90610d22565b80601f016020809104026020016040519081016040528092919081815260200182805461031690610d22565b80156103635780601f1061033857610100808354040283529160200191610363565b820191906000526020600020905b81548152906001019060200180831161034657829003601f168201915b505050505090508051600003610429576000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e80546103a890610d22565b80601f01602080910402602001604051908101604052809291908181526020018280546103d490610d22565b80156104215780601f106103f657610100808354040283529160200191610421565b820191906000526020600020905b81548152906001019060200180831161040457829003601f168201915b505050505090505b919050565b61043661093d565b6001600160a01b03821661045d5760405163a9fcf0f560e01b815260040160405180910390fd5b6001600160a01b038216600090815260986020526040902061047f8282610dab565b50816001600160a01b03167f6004b71123e07b97df793497325c4438343da4eeb06cfe39475aa69d93476527826040516104b99190610b03565b60405180910390a25050565b600054610100900460ff16158080156104e55750600054600160ff909116105b806104ff5750303b1580156104ff575060005460ff166001145b6105675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801561058a576000805461ff0019166101001790555b6001600160a01b0384166105d85760405162461bcd60e51b81526020600482015260156024820152744f776e6572206973207a65726f206164647265737360581b604482015260640161055e565b6105e184610997565b6105ea826109b0565b6105f383610a45565b8015610639576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b61064761093d565b6106516000610997565b565b60655433906001600160a01b031681146106c15760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161055e565b6106ca81610997565b50565b6106d561093d565b6106ca81610a45565b6106e661093d565b6001600160a01b0381161561078e576040516261f76560e41b81526001600160a01b03838116600483015282169063061f765090602401602060405180830381865afa15801561073a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075e9190610e6b565b61078e5760405163e12aeae760e01b81526001600160a01b0380831660048301528316602482015260440161055e565b6001600160a01b03918216600090815260996020526040902080546001600160a01b03191691909216179055565b6107c461093d565b6106ca816109b0565b6107d561093d565b6000805260986020527fddaeee8e61001dbcfaf4f92c6943552c392a86665d734d3c1905d7b3c23b1b1e6108098282610dab565b507fe358eb330ebc40c9c9375742912f9c5a8ae1db2e9990a15039c889ba971e128b816040516108399190610b03565b60405180910390a150565b61084c61093d565b6001600160a01b039182166000908152609a6020526040902080546001600160a01b03191691909216179055565b61088261093d565b606580546001600160a01b0383166001600160a01b031990911681179091556108b36033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6033546001600160a01b031633146106515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055e565b606580546001600160a01b03191690556106ca816108eb565b6001600160a01b0381166109d757604051635fb3e86760e11b815260040160405180910390fd5b609780546001600160a01b038381166201000081810262010000600160b01b031985161790945560408051949093049091168084526020840191909152917f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f3891015b60405180910390a15050565b6103e861ffff82161115610a7a5760405163f6696bd560e01b815261ffff821660048201526103e8602482015260440161055e565b6097805461ffff83811661ffff1983168117909355604080519190921680825260208201939093527f2e7c4279000925b8ff0bca0e7109cbc47fc6f6c4edfb831ffe7466cf0af07fa09101610a39565b80356001600160a01b038116811461042957600080fd5b600060208284031215610af357600080fd5b610afc82610aca565b9392505050565b600060208083528351808285015260005b81811015610b3057858101830151858201604001528201610b14565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610b7857600080fd5b813567ffffffffffffffff80821115610b9357610b93610b51565b604051601f8301601f19908116603f01168101908282118183101715610bbb57610bbb610b51565b81604052838152866020858801011115610bd457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610c0757600080fd5b610c1083610aca565b9150602083013567ffffffffffffffff811115610c2c57600080fd5b610c3885828601610b67565b9150509250929050565b803561ffff8116811461042957600080fd5b600080600060608486031215610c6957600080fd5b610c7284610aca565b9250610c8060208501610c42565b9150610c8e60408501610aca565b90509250925092565b600060208284031215610ca957600080fd5b610afc82610c42565b60008060408385031215610cc557600080fd5b610cce83610aca565b9150610cdc60208401610aca565b90509250929050565b600060208284031215610cf757600080fd5b813567ffffffffffffffff811115610d0e57600080fd5b610d1a84828501610b67565b949350505050565b600181811c90821680610d3657607f821691505b602082108103610d5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610da657600081815260208120601f850160051c81016020861015610d835750805b601f850160051c820191505b81811015610da257828155600101610d8f565b5050505b505050565b815167ffffffffffffffff811115610dc557610dc5610b51565b610dd981610dd38454610d22565b84610d5c565b602080601f831160018114610e0e5760008415610df65750858301515b600019600386901b1c1916600185901b178555610da2565b600085815260208120601f198616915b82811015610e3d57888601518255948401946001909101908401610e1e565b5085821015610e5b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215610e7d57600080fd5b81518015158114610afc57600080fdfea264697066735822122050013480b7b3f1ae431e986d3a9984428851eaf65c04a2b9cba92ca8ac167a2164736f6c63430008100033","sourceMap":"497:8860:80:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6987:312;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7713:179;;;;;;:::i;:::-;-1:-1:-1;;;;;7858:26:80;;;7788:25;7858:26;;;:19;:26;;;;;;;;7713:179;;;;-1:-1:-1;;;;;1135:32:137;;;1117:51;;1105:2;1090:18;7713:179:80;936:238:137;5990:423:80;;;;;;:::i;:::-;;:::i;:::-;;3774:264;;;;;;:::i;:::-;;:::i;2085:101:26:-;;;:::i;2031:212:25:-;;;:::i;1462:85:26:-;1534:6;;-1:-1:-1;;;;;1534:6:26;1462:85;;4380:78:80;;;;;;:::i;:::-;;:::i;8146:346::-;;;;;;:::i;:::-;;:::i;4980:115::-;;;;;;:::i;:::-;;:::i;8886:139::-;;;;;;:::i;:::-;-1:-1:-1;;;;;8991:26:80;;;8947:12;8991:26;;;:20;:26;;;;;;;;8886:139;799:37;;832:4;799:37;;;;;4003:6:137;3991:19;;;3973:38;;3961:2;3946:18;799:37:80;3829:188:137;1045:27:80;;;;;;;;-1:-1:-1;;;;;1045:27:80;;;6561:197;;;;;;:::i;:::-;;:::i;9222:132::-;;;;;;:::i;:::-;;:::i;953:17::-;;;;;;;;;1144:99:25;1223:13;;-1:-1:-1;;;;;1223:13:25;1144:99;;1436:178;;;;;;:::i;:::-;;:::i;6987:312:80:-;-1:-1:-1;;;;;7092:30:80;;;;;;:16;:30;;;;;7086:36;;7057:17;;7092:30;7086:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7228:3;7222:17;7243:1;7222:22;7218:74;;7264:28;;;:16;:28;;;7258:34;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7218:74;6987:312;;;:::o;5990:423::-;1355:13:26;:11;:13::i;:::-;-1:-1:-1;;;;;6100:26:80;::::1;6096:191;;6269:18;;-1:-1:-1::0;;;6269:18:80::1;;;;;;;;;;;6096:191;-1:-1:-1::0;;;;;6298:30:80;::::1;;::::0;;;:16:::1;:30;::::0;;;;:44:::1;6331:11:::0;6298:30;:44:::1;:::i;:::-;;6380:12;-1:-1:-1::0;;;;;6357:49:80::1;;6394:11;6357:49;;;;;;:::i;:::-;;;;;;;;5990:423:::0;;:::o;3774:264::-;3279:19:27;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:27;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:27;1713:19:28;:23;;;3387:66:27;;-1:-1:-1;3436:12:27;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:27;;7140:2:137;3325:201:27;;;7122:21:137;7179:2;7159:18;;;7152:30;7218:34;7198:18;;;7191:62;-1:-1:-1;;;7269:18:137;;;7262:44;7323:19;;3325:201:27;;;;;;;;;3536:12;:16;;-1:-1:-1;;3536:16:27;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;-1:-1:-1;;3596:20:27;;;;;3562:65;-1:-1:-1;;;;;3885:20:80;::::1;3877:54;;;::::0;-1:-1:-1;;;3877:54:80;;7555:2:137;3877:54:80::1;::::0;::::1;7537:21:137::0;7594:2;7574:18;;;7567:30;-1:-1:-1;;;7613:18:137;;;7606:51;7674:18;;3877:54:80::1;7353:345:137::0;3877:54:80::1;3941:26;3960:6;3941:18;:26::i;:::-;3977:31;3994:13;3977:16;:31::i;:::-;4018:13;4026:4;4018:7;:13::i;:::-;3651:14:27::0;3647:99;;;3697:5;3681:21;;-1:-1:-1;;3681:21:27;;;3721:14;;-1:-1:-1;7855:36:137;;3721:14:27;;7843:2:137;7828:18;3721:14:27;;;;;;;3647:99;3269:483;3774:264:80;;;:::o;2085:101:26:-;1355:13;:11;:13::i;:::-;2149:30:::1;2176:1;2149:18;:30::i;:::-;2085:101::o:0;2031:212:25:-;1223:13;;965:10:29;;-1:-1:-1;;;;;1223:13:25;2130:24;;2122:78;;;;-1:-1:-1;;;2122:78:25;;8104:2:137;2122:78:25;;;8086:21:137;8143:2;8123:18;;;8116:30;8182:34;8162:18;;;8155:62;-1:-1:-1;;;8233:18:137;;;8226:39;8282:19;;2122:78:25;7902:405:137;2122:78:25;2210:26;2229:6;2210:18;:26::i;:::-;2073:170;2031:212::o;4380:78:80:-;1355:13:26;:11;:13::i;:::-;4438::80::1;4446:4;4438:7;:13::i;8146:346::-:0;1355:13:26;:11;:13::i;:::-;-1:-1:-1;;;;;8254:22:80;::::1;::::0;8250:187:::1;;8295:56;::::0;-1:-1:-1;;;8295:56:80;;-1:-1:-1;;;;;1135:32:137;;;8295:56:80::1;::::0;::::1;1117:51:137::0;8295:49:80;::::1;::::0;::::1;::::0;1090:18:137;;8295:56:80::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8290:147;;8376:61;::::0;-1:-1:-1;;;8376:61:80;;-1:-1:-1;;;;;8824:15:137;;;8376:61:80::1;::::0;::::1;8806:34:137::0;8876:15;;8856:18;;;8849:43;8741:18;;8376:61:80::1;8594:304:137::0;8290:147:80::1;-1:-1:-1::0;;;;;8448:26:80;;::::1;;::::0;;;:19:::1;:26;::::0;;;;:37;;-1:-1:-1;;;;;;8448:37:80::1;::::0;;;::::1;;::::0;;8146:346::o;4980:115::-;1355:13:26;:11;:13::i;:::-;5057:31:80::1;5074:13;5057:16;:31::i;6561:197::-:0;1355:13:26;:11;:13::i;:::-;6652:28:80::1;::::0;;:16:::1;:28;::::0;;:42:::1;6683:11:::0;6652:28;:42:::1;:::i;:::-;;6709;6739:11;6709:42;;;;;;:::i;:::-;;;;;;;;6561:197:::0;:::o;9222:132::-;1355:13:26;:11;:13::i;:::-;-1:-1:-1;;;;;9311:26:80;;::::1;;::::0;;;:20:::1;:26;::::0;;;;:36;;-1:-1:-1;;;;;;9311:36:80::1;::::0;;;::::1;;::::0;;9222:132::o;1436:178:25:-;1355:13:26;:11;:13::i;:::-;1525::25::1;:24:::0;;-1:-1:-1;;;;;1525:24:25;::::1;-1:-1:-1::0;;;;;;1525:24:25;;::::1;::::0;::::1;::::0;;;1589:7:::1;1534:6:26::0;;-1:-1:-1;;;;;1534:6:26;;1462:85;1589:7:25::1;-1:-1:-1::0;;;;;1564:43:25::1;;;;;;;;;;;1436:178:::0;:::o;2687:187:26:-;2779:6;;;-1:-1:-1;;;;;2795:17:26;;;-1:-1:-1;;;;;;2795:17:26;;;;;;;2827:40;;2779:6;;;2795:17;2779:6;;2827:40;;2760:16;;2827:40;2750:124;2687:187;:::o;1620:130::-;1534:6;;-1:-1:-1;;;;;1534:6:26;965:10:29;1683:23:26;1675:68;;;;-1:-1:-1;;;1675:68:26;;9105:2:137;1675:68:26;;;9087:21:137;;;9124:18;;;9117:30;9183:34;9163:18;;;9156:62;9235:18;;1675:68:26;8903:356:137;1798:153:25;1887:13;1880:20;;-1:-1:-1;;;;;;1880:20:25;;;1910:34;1935:8;1910:24;:34::i;5249:297:80:-;-1:-1:-1;;;;;5320:27:80;;5316:70;;5368:18;;-1:-1:-1;;;5368:18:80;;;;;;;;;;;5316:70;5423:12;;;-1:-1:-1;;;;;5445:28:80;;;5423:12;5445:28;;;-1:-1:-1;;;;;;5445:28:80;;;;;;5488:51;;;5423:12;;;;;;;8806:34:137;;;8871:2;8856:18;;8849:43;;;;5423:12:80;5488:51;;8741:18:137;5488:51:80;;;;;;;;5306:240;5249:297;:::o;4628:229::-;832:4;4680:14;;;;4676:85;;;4715:46;;-1:-1:-1;;;4715:46:80;;9446:6:137;9479:15;;4715:46:80;;;9461:34:137;832:4:80;9511:18:137;;;9504:43;9409:18;;4715:46:80;9264:289:137;4676:85:80;4788:3;;;;4801:10;;;-1:-1:-1;;4801:10:80;;;;;;;4826:24;;;4788:3;;;;9461:34:137;;;9526:2;9511:18;;9504:43;;;;4826:24:80;;9409:18:137;4826:24:80;9264:289:137;14:173;82:20;;-1:-1:-1;;;;;131:31:137;;121:42;;111:70;;177:1;174;167:12;192:186;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;:::-;333:39;192:186;-1:-1:-1;;;192:186:137:o;383:548::-;495:4;524:2;553;542:9;535:21;585:6;579:13;628:6;623:2;612:9;608:18;601:34;653:1;663:140;677:6;674:1;671:13;663:140;;;772:14;;;768:23;;762:30;738:17;;;757:2;734:26;727:66;692:10;;663:140;;;667:3;852:1;847:2;838:6;827:9;823:22;819:31;812:42;922:2;915;911:7;906:2;898:6;894:15;890:29;879:9;875:45;871:54;863:62;;;;383:548;;;;:::o;1179:127::-;1240:10;1235:3;1231:20;1228:1;1221:31;1271:4;1268:1;1261:15;1295:4;1292:1;1285:15;1311:719;1354:5;1407:3;1400:4;1392:6;1388:17;1384:27;1374:55;;1425:1;1422;1415:12;1374:55;1461:6;1448:20;1487:18;1524:2;1520;1517:10;1514:36;;;1530:18;;:::i;:::-;1605:2;1599:9;1573:2;1659:13;;-1:-1:-1;;1655:22:137;;;1679:2;1651:31;1647:40;1635:53;;;1703:18;;;1723:22;;;1700:46;1697:72;;;1749:18;;:::i;:::-;1789:10;1785:2;1778:22;1824:2;1816:6;1809:18;1870:3;1863:4;1858:2;1850:6;1846:15;1842:26;1839:35;1836:55;;;1887:1;1884;1877:12;1836:55;1951:2;1944:4;1936:6;1932:17;1925:4;1917:6;1913:17;1900:54;1998:1;1991:4;1986:2;1978:6;1974:15;1970:26;1963:37;2018:6;2009:15;;;;;;1311:719;;;;:::o;2035:396::-;2113:6;2121;2174:2;2162:9;2153:7;2149:23;2145:32;2142:52;;;2190:1;2187;2180:12;2142:52;2213:29;2232:9;2213:29;:::i;:::-;2203:39;;2293:2;2282:9;2278:18;2265:32;2320:18;2312:6;2309:30;2306:50;;;2352:1;2349;2342:12;2306:50;2375;2417:7;2408:6;2397:9;2393:22;2375:50;:::i;:::-;2365:60;;;2035:396;;;;;:::o;2436:159::-;2503:20;;2563:6;2552:18;;2542:29;;2532:57;;2585:1;2582;2575:12;2600:332;2676:6;2684;2692;2745:2;2733:9;2724:7;2720:23;2716:32;2713:52;;;2761:1;2758;2751:12;2713:52;2784:29;2803:9;2784:29;:::i;:::-;2774:39;;2832:37;2865:2;2854:9;2850:18;2832:37;:::i;:::-;2822:47;;2888:38;2922:2;2911:9;2907:18;2888:38;:::i;:::-;2878:48;;2600:332;;;;;:::o;3145:184::-;3203:6;3256:2;3244:9;3235:7;3231:23;3227:32;3224:52;;;3272:1;3269;3262:12;3224:52;3295:28;3313:9;3295:28;:::i;3334:260::-;3402:6;3410;3463:2;3451:9;3442:7;3438:23;3434:32;3431:52;;;3479:1;3476;3469:12;3431:52;3502:29;3521:9;3502:29;:::i;:::-;3492:39;;3550:38;3584:2;3573:9;3569:18;3550:38;:::i;:::-;3540:48;;3334:260;;;;;:::o;4022:322::-;4091:6;4144:2;4132:9;4123:7;4119:23;4115:32;4112:52;;;4160:1;4157;4150:12;4112:52;4200:9;4187:23;4233:18;4225:6;4222:30;4219:50;;;4265:1;4262;4255:12;4219:50;4288;4330:7;4321:6;4310:9;4306:22;4288:50;:::i;:::-;4278:60;4022:322;-1:-1:-1;;;;4022:322:137:o;4349:380::-;4428:1;4424:12;;;;4471;;;4492:61;;4546:4;4538:6;4534:17;4524:27;;4492:61;4599:2;4591:6;4588:14;4568:18;4565:38;4562:161;;4645:10;4640:3;4636:20;4633:1;4626:31;4680:4;4677:1;4670:15;4708:4;4705:1;4698:15;4562:161;;4349:380;;;:::o;4860:545::-;4962:2;4957:3;4954:11;4951:448;;;4998:1;5023:5;5019:2;5012:17;5068:4;5064:2;5054:19;5138:2;5126:10;5122:19;5119:1;5115:27;5109:4;5105:38;5174:4;5162:10;5159:20;5156:47;;;-1:-1:-1;5197:4:137;5156:47;5252:2;5247:3;5243:12;5240:1;5236:20;5230:4;5226:31;5216:41;;5307:82;5325:2;5318:5;5315:13;5307:82;;;5370:17;;;5351:1;5340:13;5307:82;;;5311:3;;;4951:448;4860:545;;;:::o;5581:1352::-;5707:3;5701:10;5734:18;5726:6;5723:30;5720:56;;;5756:18;;:::i;:::-;5785:97;5875:6;5835:38;5867:4;5861:11;5835:38;:::i;:::-;5829:4;5785:97;:::i;:::-;5937:4;;6001:2;5990:14;;6018:1;6013:663;;;;6720:1;6737:6;6734:89;;;-1:-1:-1;6789:19:137;;;6783:26;6734:89;-1:-1:-1;;5538:1:137;5534:11;;;5530:24;5526:29;5516:40;5562:1;5558:11;;;5513:57;6836:81;;5983:944;;6013:663;4807:1;4800:14;;;4844:4;4831:18;;-1:-1:-1;;6049:20:137;;;6167:236;6181:7;6178:1;6175:14;6167:236;;;6270:19;;;6264:26;6249:42;;6362:27;;;;6330:1;6318:14;;;;6197:19;;6167:236;;;6171:3;6431:6;6422:7;6419:19;6416:201;;;6492:19;;;6486:26;-1:-1:-1;;6575:1:137;6571:14;;;6587:3;6567:24;6563:37;6559:42;6544:58;6529:74;;6416:201;-1:-1:-1;;;;;6663:1:137;6647:14;;;6643:22;6630:36;;-1:-1:-1;5581:1352:137:o;8312:277::-;8379:6;8432:2;8420:9;8411:7;8407:23;8403:32;8400:52;;;8448:1;8445;8438:12;8400:52;8480:9;8474:16;8533:5;8526:13;8519:21;8512:5;8509:32;8499:60;;8555:1;8552;8545:12","linkReferences":{}},"methodIdentifiers":{"MAX_FEE()":"bc063e1a","acceptOwnership()":"79ba5097","fee()":"ddca3f43","feeCollector()":"c415b95c","getPoolAdapter(address)":"b2091231","getStateFingerprintComputer(address)":"2df927ac","initialize(address,uint16,address)":"708c0db9","loanMetadataUri(address)":"23355750","owner()":"8da5cb5b","pendingOwner()":"e30c3978","registerPoolAdapter(address,address)":"cbf35d88","registerStateFingerprintComputer(address,address)":"935bf0d7","renounceOwnership()":"715018a6","setDefaultLOANMetadataUri(string)":"c4743ae0","setFee(uint16)":"8e005553","setFeeCollector(address)":"a42dce80","setLOANMetadataUri(address,string)":"4bbcf8de","transferOwnership(address)":"f2fde38b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"computer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"InvalidComputerContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InvalidFeeValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroFeeCollector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroLoanContract\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newUri\",\"type\":\"string\"}],\"name\":\"DefaultLOANMetadataUriUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeCollector\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeCollector\",\"type\":\"address\"}],\"name\":\"FeeCollectorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"oldFee\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"newFee\",\"type\":\"uint16\"}],\"name\":\"FeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newUri\",\"type\":\"string\"}],\"name\":\"LOANMetadataUriUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_FEE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeCollector\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"getPoolAdapter\",\"outputs\":[{\"internalType\":\"contract IPoolAdapter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getStateFingerprintComputer\",\"outputs\":[{\"internalType\":\"contract IStateFingerpringComputer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"_fee\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"_feeCollector\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"}],\"name\":\"loanMetadataUri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"uri\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"adapter\",\"type\":\"address\"}],\"name\":\"registerPoolAdapter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"computer\",\"type\":\"address\"}],\"name\":\"registerStateFingerprintComputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"metadataUri\",\"type\":\"string\"}],\"name\":\"setDefaultLOANMetadataUri\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_fee\",\"type\":\"uint16\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_feeCollector\",\"type\":\"address\"}],\"name\":\"setFeeCollector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"metadataUri\",\"type\":\"string\"}],\"name\":\"setLOANMetadataUri\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Is intended to be used as a proxy via `TransparentUpgradeableProxy`.\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"getPoolAdapter(address)\":{\"params\":{\"pool\":\"The pool for which the adapter is requested.\"},\"returns\":{\"_0\":\"The adapter for the given pool.\"}},\"getStateFingerprintComputer(address)\":{\"params\":{\"asset\":\"The asset for which the computer is requested.\"},\"returns\":{\"_0\":\"The computer for the given asset.\"}},\"loanMetadataUri(address)\":{\"params\":{\"loanContract\":\"Address of a loan contract.\"},\"returns\":{\"uri\":\"Metadata uri for given loan contract.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"registerPoolAdapter(address,address)\":{\"params\":{\"adapter\":\"The adapter to be registered.\",\"pool\":\"The pool for which the adapter is registered.\"}},\"registerStateFingerprintComputer(address,address)\":{\"params\":{\"asset\":\"The asset for which the computer is registered.\",\"computer\":\"The computer to be registered. Use address(0) to remove a computer.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setDefaultLOANMetadataUri(string)\":{\"params\":{\"metadataUri\":\"New value of default LOAN token metadata uri.\"}},\"setFee(uint16)\":{\"params\":{\"_fee\":\"New fee value in basis points. Value of 100 is 1% fee.\"}},\"setFeeCollector(address)\":{\"params\":{\"_feeCollector\":\"New fee collector address.\"}},\"setLOANMetadataUri(address,string)\":{\"params\":{\"loanContract\":\"Address of a loan contract.\",\"metadataUri\":\"New value of LOAN token metadata uri for given `loanContract`.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"stateVariables\":{\"_loanMetadataUri\":{\"details\":\"LOAN token minted by a loan contract will return metadata uri stored in this mapping. If there is no metadata uri for a loan contract, default metadata uri will be used stored under address(0).\"},\"fee\":{\"details\":\"Value of 100 is 1% fee.\"}},\"title\":\"PWN Config\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidComputerContract(address,address)\":[{\"notice\":\"Thrown when registering a computer which does not support the asset it is registered for.\"}],\"InvalidFeeValue(uint256,uint256)\":[{\"notice\":\"Thrown when trying to set a fee value higher than `MAX_FEE`.\"}],\"ZeroFeeCollector()\":[{\"notice\":\"Thrown when trying to set a fee collector to zero address.\"}],\"ZeroLoanContract()\":[{\"notice\":\"Thrown when trying to set a LOAN token metadata uri for zero address loan contract.\"}]},\"events\":{\"DefaultLOANMetadataUriUpdated(string)\":{\"notice\":\"Emitted when new default LOAN token metadata uri is set.\"},\"FeeCollectorUpdated(address,address)\":{\"notice\":\"Emitted when new fee collector address is set.\"},\"FeeUpdated(uint16,uint16)\":{\"notice\":\"Emitted when new fee value is set.\"},\"LOANMetadataUriUpdated(address,string)\":{\"notice\":\"Emitted when new LOAN token metadata uri is set.\"}},\"kind\":\"user\",\"methods\":{\"fee()\":{\"notice\":\"Protocol fee value in basis points.\"},\"feeCollector()\":{\"notice\":\"Address that collects protocol fees.\"},\"getPoolAdapter(address)\":{\"notice\":\"Returns the pool adapter for a given pool.\"},\"getStateFingerprintComputer(address)\":{\"notice\":\"Returns the state fingerprint computer for a given asset.\"},\"loanMetadataUri(address)\":{\"notice\":\"Return a LOAN token metadata uri base on a loan contract that minted the token.\"},\"registerPoolAdapter(address,address)\":{\"notice\":\"Registers a pool adapter for a given pool.\"},\"registerStateFingerprintComputer(address,address)\":{\"notice\":\"Registers a state fingerprint computer for a given asset.\"},\"setDefaultLOANMetadataUri(string)\":{\"notice\":\"Set a default LOAN token metadata uri.\"},\"setFee(uint16)\":{\"notice\":\"Set new protocol fee value.\"},\"setFeeCollector(address)\":{\"notice\":\"Set new fee collector address.\"},\"setLOANMetadataUri(address,string)\":{\"notice\":\"Set a LOAN token metadata uri for a specific loan contract.\"}},\"notice\":\"Contract holding configurable values of PWN protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/config/PWNConfig.sol\":\"PWNConfig\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\":{\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16\",\"dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c\",\"dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e\",\"dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b\",\"dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95\",\"dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx\"]},\"src/config/PWNConfig.sol\":{\"keccak256\":\"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7\",\"dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz\"]},\"src/interfaces/IPoolAdapter.sol\":{\"keccak256\":\"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b\",\"dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T\"]},\"src/interfaces/IStateFingerpringComputer.sol\":{\"keccak256\":\"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c\",\"dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"computer","type":"address"},{"internalType":"address","name":"asset","type":"address"}],"type":"error","name":"InvalidComputerContract"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InvalidFeeValue"},{"inputs":[],"type":"error","name":"ZeroFeeCollector"},{"inputs":[],"type":"error","name":"ZeroLoanContract"},{"inputs":[{"internalType":"string","name":"newUri","type":"string","indexed":false}],"type":"event","name":"DefaultLOANMetadataUriUpdated","anonymous":false},{"inputs":[{"internalType":"address","name":"oldFeeCollector","type":"address","indexed":false},{"internalType":"address","name":"newFeeCollector","type":"address","indexed":false}],"type":"event","name":"FeeCollectorUpdated","anonymous":false},{"inputs":[{"internalType":"uint16","name":"oldFee","type":"uint16","indexed":false},{"internalType":"uint16","name":"newFee","type":"uint16","indexed":false}],"type":"event","name":"FeeUpdated","anonymous":false},{"inputs":[{"internalType":"uint8","name":"version","type":"uint8","indexed":false}],"type":"event","name":"Initialized","anonymous":false},{"inputs":[{"internalType":"address","name":"loanContract","type":"address","indexed":true},{"internalType":"string","name":"newUri","type":"string","indexed":false}],"type":"event","name":"LOANMetadataUriUpdated","anonymous":false},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferStarted","anonymous":false},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferred","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"MAX_FEE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"acceptOwnership"},{"inputs":[],"stateMutability":"view","type":"function","name":"fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"view","type":"function","name":"getPoolAdapter","outputs":[{"internalType":"contract IPoolAdapter","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"stateMutability":"view","type":"function","name":"getStateFingerprintComputer","outputs":[{"internalType":"contract IStateFingerpringComputer","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint16","name":"_fee","type":"uint16"},{"internalType":"address","name":"_feeCollector","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"initialize"},{"inputs":[{"internalType":"address","name":"loanContract","type":"address"}],"stateMutability":"view","type":"function","name":"loanMetadataUri","outputs":[{"internalType":"string","name":"uri","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"adapter","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"registerPoolAdapter"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"computer","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"registerStateFingerprintComputer"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"renounceOwnership"},{"inputs":[{"internalType":"string","name":"metadataUri","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"setDefaultLOANMetadataUri"},{"inputs":[{"internalType":"uint16","name":"_fee","type":"uint16"}],"stateMutability":"nonpayable","type":"function","name":"setFee"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"setFeeCollector"},{"inputs":[{"internalType":"address","name":"loanContract","type":"address"},{"internalType":"string","name":"metadataUri","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"setLOANMetadataUri"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"transferOwnership"}],"devdoc":{"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"getPoolAdapter(address)":{"params":{"pool":"The pool for which the adapter is requested."},"returns":{"_0":"The adapter for the given pool."}},"getStateFingerprintComputer(address)":{"params":{"asset":"The asset for which the computer is requested."},"returns":{"_0":"The computer for the given asset."}},"loanMetadataUri(address)":{"params":{"loanContract":"Address of a loan contract."},"returns":{"uri":"Metadata uri for given loan contract."}},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"registerPoolAdapter(address,address)":{"params":{"adapter":"The adapter to be registered.","pool":"The pool for which the adapter is registered."}},"registerStateFingerprintComputer(address,address)":{"params":{"asset":"The asset for which the computer is registered.","computer":"The computer to be registered. Use address(0) to remove a computer."}},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."},"setDefaultLOANMetadataUri(string)":{"params":{"metadataUri":"New value of default LOAN token metadata uri."}},"setFee(uint16)":{"params":{"_fee":"New fee value in basis points. Value of 100 is 1% fee."}},"setFeeCollector(address)":{"params":{"_feeCollector":"New fee collector address."}},"setLOANMetadataUri(address,string)":{"params":{"loanContract":"Address of a loan contract.","metadataUri":"New value of LOAN token metadata uri for given `loanContract`."}},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner."}},"version":1},"userdoc":{"kind":"user","methods":{"fee()":{"notice":"Protocol fee value in basis points."},"feeCollector()":{"notice":"Address that collects protocol fees."},"getPoolAdapter(address)":{"notice":"Returns the pool adapter for a given pool."},"getStateFingerprintComputer(address)":{"notice":"Returns the state fingerprint computer for a given asset."},"loanMetadataUri(address)":{"notice":"Return a LOAN token metadata uri base on a loan contract that minted the token."},"registerPoolAdapter(address,address)":{"notice":"Registers a pool adapter for a given pool."},"registerStateFingerprintComputer(address,address)":{"notice":"Registers a state fingerprint computer for a given asset."},"setDefaultLOANMetadataUri(string)":{"notice":"Set a default LOAN token metadata uri."},"setFee(uint16)":{"notice":"Set new protocol fee value."},"setFeeCollector(address)":{"notice":"Set new fee collector address."},"setLOANMetadataUri(address,string)":{"notice":"Set a LOAN token metadata uri for a specific loan contract."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/config/PWNConfig.sol":"PWNConfig"},"evmVersion":"london","libraries":{}},"sources":{"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol":{"keccak256":"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510","urls":["bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16","dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"keccak256":"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e","urls":["bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c","dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794","urls":["bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e","dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"keccak256":"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422","urls":["bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b","dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef","urls":["bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95","dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx"],"license":"MIT"},"src/config/PWNConfig.sol":{"keccak256":"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f","urls":["bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7","dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz"],"license":"GPL-3.0-only"},"src/interfaces/IPoolAdapter.sol":{"keccak256":"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89","urls":["bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b","dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T"],"license":"GPL-3.0-only"},"src/interfaces/IStateFingerpringComputer.sol":{"keccak256":"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2","urls":["bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c","dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct"],"license":"GPL-3.0-only"}},"version":1},"id":80} \ No newline at end of file +[ + { + "inputs": [ + { "internalType": "address", "name": "_logic", "type": "address" }, + { "internalType": "address", "name": "admin_", "type": "address" }, + { "internalType": "bytes", "name": "_data", "type": "bytes" } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { "stateMutability": "payable", "type": "fallback" }, + { "stateMutability": "payable", "type": "receive" }, + { "type": "constructor", "inputs": [], "stateMutability": "nonpayable" }, + { + "type": "function", + "name": "MAX_FEE", + "inputs": [], + "outputs": [{ "name": "", "type": "uint16", "internalType": "uint16" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "acceptOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "fee", + "inputs": [], + "outputs": [{ "name": "", "type": "uint16", "internalType": "uint16" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "feeCollector", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getPoolAdapter", + "inputs": [ + { "name": "pool", "type": "address", "internalType": "address" } + ], + "outputs": [ + { "name": "", "type": "address", "internalType": "contract IPoolAdapter" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getStateFingerprintComputer", + "inputs": [ + { "name": "asset", "type": "address", "internalType": "address" } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IStateFingerpringComputer" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "_owner", "type": "address", "internalType": "address" }, + { "name": "_fee", "type": "uint16", "internalType": "uint16" }, + { "name": "_feeCollector", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "loanMetadataUri", + "inputs": [ + { "name": "loanContract", "type": "address", "internalType": "address" } + ], + "outputs": [{ "name": "uri", "type": "string", "internalType": "string" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pendingOwner", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "registerPoolAdapter", + "inputs": [ + { "name": "pool", "type": "address", "internalType": "address" }, + { "name": "adapter", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "registerStateFingerprintComputer", + "inputs": [ + { "name": "asset", "type": "address", "internalType": "address" }, + { "name": "computer", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setDefaultLOANMetadataUri", + "inputs": [ + { "name": "metadataUri", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFee", + "inputs": [{ "name": "_fee", "type": "uint16", "internalType": "uint16" }], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFeeCollector", + "inputs": [ + { "name": "_feeCollector", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setLOANMetadataUri", + "inputs": [ + { "name": "loanContract", "type": "address", "internalType": "address" }, + { "name": "metadataUri", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { "name": "newOwner", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "DefaultLOANMetadataUriUpdated", + "inputs": [ + { + "name": "newUri", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeCollectorUpdated", + "inputs": [ + { + "name": "oldFeeCollector", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "newFeeCollector", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeUpdated", + "inputs": [ + { + "name": "oldFee", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + }, + { + "name": "newFee", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LOANMetadataUriUpdated", + "inputs": [ + { + "name": "loanContract", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newUri", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferStarted", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "InvalidComputerContract", + "inputs": [ + { "name": "computer", "type": "address", "internalType": "address" }, + { "name": "asset", "type": "address", "internalType": "address" } + ] + }, + { + "type": "error", + "name": "InvalidFeeValue", + "inputs": [ + { "name": "fee", "type": "uint256", "internalType": "uint256" }, + { "name": "limit", "type": "uint256", "internalType": "uint256" } + ] + }, + { "type": "error", "name": "ZeroFeeCollector", "inputs": [] }, + { "type": "error", "name": "ZeroLoanContract", "inputs": [] } +] diff --git a/packages/subgraph/abis/Hub.json b/packages/subgraph/abis/Hub.json index 3f419619..ed06efcb 100644 --- a/packages/subgraph/abis/Hub.json +++ b/packages/subgraph/abis/Hub.json @@ -1 +1,198 @@ -{"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"acceptOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"hasTag","inputs":[{"name":"_address","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"pendingOwner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setTag","inputs":[{"name":"_address","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"},{"name":"_hasTag","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setTags","inputs":[{"name":"_addresses","type":"address[]","internalType":"address[]"},{"name":"_tags","type":"bytes32[]","internalType":"bytes32[]"},{"name":"_hasTag","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"TagSet","inputs":[{"name":"_address","type":"address","indexed":true,"internalType":"address"},{"name":"tag","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"hasTag","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"error","name":"InvalidInputData","inputs":[]}],"bytecode":{"object":"0x608060405234801561001057600080fd5b5061001a3361001f565b610096565b600180546001600160a01b031916905561004381610046602090811b61035617901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6106b6806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063d019577a1161005b578063d019577a146100dc578063e30c397814610125578063f12715a114610136578063f2fde38b1461014957600080fd5b8063715018a61461008d57806379ba5097146100975780638da5cb5b1461009f5780639cd9c520146100c9575b600080fd5b61009561015c565b005b610095610170565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100956100d7366004610445565b6101ef565b6101156100ea366004610481565b6001600160a01b03919091166000908152600260209081526040808320938352929052205460ff1690565b60405190151581526020016100c0565b6001546001600160a01b03166100ac565b610095610144366004610581565b610262565b610095610157366004610648565b6102e5565b6101646103a6565b61016e6000610400565b565b60015433906001600160a01b031681146101e35760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6101ec81610400565b50565b6101f76103a6565b6001600160a01b0383166000818152600260209081526040808320868452825291829020805460ff191685151590811790915591519182528492917fb30f662698af140e14b21a677b92bf5a9787f9109294b3d206fa53ea23069d2b910160405180910390a3505050565b61026a6103a6565b815183511461028c57604051637016bd9b60e01b815260040160405180910390fd5b815160005b818110156102de576102d68582815181106102ae576102ae61066a565b60200260200101518583815181106102c8576102c861066a565b6020026020010151856101ef565b600101610291565b5050505050565b6102ed6103a6565b600180546001600160a01b0383166001600160a01b0319909116811790915561031e6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b0316331461016e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101da565b600180546001600160a01b03191690556101ec81610356565b80356001600160a01b038116811461043057600080fd5b919050565b8035801515811461043057600080fd5b60008060006060848603121561045a57600080fd5b61046384610419565b92506020840135915061047860408501610435565b90509250925092565b6000806040838503121561049457600080fd5b61049d83610419565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156104ea576104ea6104ab565b604052919050565b600067ffffffffffffffff82111561050c5761050c6104ab565b5060051b60200190565b600082601f83011261052757600080fd5b8135602061053c610537836104f2565b6104c1565b82815260059290921b8401810191818101908684111561055b57600080fd5b8286015b84811015610576578035835291830191830161055f565b509695505050505050565b60008060006060848603121561059657600080fd5b833567ffffffffffffffff808211156105ae57600080fd5b818601915086601f8301126105c257600080fd5b813560206105d2610537836104f2565b82815260059290921b8401810191818101908a8411156105f157600080fd5b948201945b838610156106165761060786610419565b825294820194908201906105f6565b9750508701359250508082111561062c57600080fd5b5061063986828701610516565b92505061047860408501610435565b60006020828403121561065a57600080fd5b61066382610419565b9392505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220a22c2d5c2ba59f3e59dcc0860c2c2196de14c8ff50cf110a658ccc33011c5cf864736f6c63430008100033","sourceMap":"230:3317:81:-:0;;;1509:37;;;;;;;;;-1:-1:-1;936:32:32;734:10:61;936:18:32;:32::i;:::-;230:3317:81;;1501:153:33;1590:13;1583:20;;-1:-1:-1;;;;;;1583:20:33;;;1613:34;1638:8;1613:24;;;;;;;:34;;:::i;:::-;1501:153;:::o;2426:187:32:-;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:32;;;-1:-1:-1;;;;;;2534:17:32;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;230:3317:81:-;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063d019577a1161005b578063d019577a146100dc578063e30c397814610125578063f12715a114610136578063f2fde38b1461014957600080fd5b8063715018a61461008d57806379ba5097146100975780638da5cb5b1461009f5780639cd9c520146100c9575b600080fd5b61009561015c565b005b610095610170565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100956100d7366004610445565b6101ef565b6101156100ea366004610481565b6001600160a01b03919091166000908152600260209081526040808320938352929052205460ff1690565b60405190151581526020016100c0565b6001546001600160a01b03166100ac565b610095610144366004610581565b610262565b610095610157366004610648565b6102e5565b6101646103a6565b61016e6000610400565b565b60015433906001600160a01b031681146101e35760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6101ec81610400565b50565b6101f76103a6565b6001600160a01b0383166000818152600260209081526040808320868452825291829020805460ff191685151590811790915591519182528492917fb30f662698af140e14b21a677b92bf5a9787f9109294b3d206fa53ea23069d2b910160405180910390a3505050565b61026a6103a6565b815183511461028c57604051637016bd9b60e01b815260040160405180910390fd5b815160005b818110156102de576102d68582815181106102ae576102ae61066a565b60200260200101518583815181106102c8576102c861066a565b6020026020010151856101ef565b600101610291565b5050505050565b6102ed6103a6565b600180546001600160a01b0383166001600160a01b0319909116811790915561031e6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b0316331461016e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101da565b600180546001600160a01b03191690556101ec81610356565b80356001600160a01b038116811461043057600080fd5b919050565b8035801515811461043057600080fd5b60008060006060848603121561045a57600080fd5b61046384610419565b92506020840135915061047860408501610435565b90509250925092565b6000806040838503121561049457600080fd5b61049d83610419565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156104ea576104ea6104ab565b604052919050565b600067ffffffffffffffff82111561050c5761050c6104ab565b5060051b60200190565b600082601f83011261052757600080fd5b8135602061053c610537836104f2565b6104c1565b82815260059290921b8401810191818101908684111561055b57600080fd5b8286015b84811015610576578035835291830191830161055f565b509695505050505050565b60008060006060848603121561059657600080fd5b833567ffffffffffffffff808211156105ae57600080fd5b818601915086601f8301126105c257600080fd5b813560206105d2610537836104f2565b82815260059290921b8401810191818101908a8411156105f157600080fd5b948201945b838610156106165761060786610419565b825294820194908201906105f6565b9750508701359250508082111561062c57600080fd5b5061063986828701610516565b92505061047860408501610435565b60006020828403121561065a57600080fd5b61066382610419565b9392505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220a22c2d5c2ba59f3e59dcc0860c2c2196de14c8ff50cf110a658ccc33011c5cf864736f6c63430008100033","sourceMap":"230:3317:81:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1824:101:32;;;:::i;:::-;;1734:212:33;;;:::i;1201:85:32:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:32;1201:85;;;-1:-1:-1;;;;;178:32:137;;;160:51;;148:2;133:18;1201:85:32;;;;;;;;2069:169:81;;;;;;:::i;:::-;;:::i;3425:119::-;;;;;;:::i;:::-;-1:-1:-1;;;;;3518:14:81;;;;3495:4;3518:14;;;:4;:14;;;;;;;;:19;;;;;;;;;;;3425:119;;;;1316:14:137;;1309:22;1291:41;;1279:2;1264:18;3425:119:81;1151:187:137;847:99:33;926:13;;-1:-1:-1;;;;;926:13:33;847:99;;2594:370:81;;;;;;:::i;:::-;;:::i;1139:178:33:-;;;;;;:::i;:::-;;:::i;1824:101:32:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;1734:212:33:-;926:13;;734:10:61;;-1:-1:-1;;;;;926:13:33;1833:24;;1825:78;;;;-1:-1:-1;;;1825:78:33;;4222:2:137;1825:78:33;;;4204:21:137;4261:2;4241:18;;;4234:30;4300:34;4280:18;;;4273:62;-1:-1:-1;;;4351:18:137;;;4344:39;4400:19;;1825:78:33;;;;;;;;;1913:26;1932:6;1913:18;:26::i;:::-;1776:170;1734:212::o;2069:169:81:-;1094:13:32;:11;:13::i;:::-;-1:-1:-1;;;;;2157:14:81;::::1;;::::0;;;:4:::1;:14;::::0;;;;;;;:19;;;;;;;;;:29;;-1:-1:-1;;2157:29:81::1;::::0;::::1;;::::0;;::::1;::::0;;;2201:30;;1291:41:137;;;2157:19:81;;:14;2201:30:::1;::::0;1264:18:137;2201:30:81::1;;;;;;;2069:169:::0;;;:::o;2594:370::-;1094:13:32;:11;:13::i;:::-;2732:5:81::1;:12;2711:10;:17;:33;2707:76;;2765:18;;-1:-1:-1::0;;;2765:18:81::1;;;;;;;;;;;2707:76;2811:12:::0;;2794:14:::1;2833:125;2853:6;2849:1;:10;2833:125;;;2876:40;2883:10;2894:1;2883:13;;;;;;;;:::i;:::-;;;;;;;2898:5;2904:1;2898:8;;;;;;;;:::i;:::-;;;;;;;2908:7;2876:6;:40::i;:::-;2942:3;;2833:125;;;;2697:267;2594:370:::0;;;:::o;1139:178:33:-;1094:13:32;:11;:13::i;:::-;1228::33::1;:24:::0;;-1:-1:-1;;;;;1228:24:33;::::1;-1:-1:-1::0;;;;;;1228:24:33;;::::1;::::0;::::1;::::0;;;1292:7:::1;1247::32::0;1273:6;-1:-1:-1;;;;;1273:6:32;;1201:85;1292:7:33::1;-1:-1:-1::0;;;;;1267:43:33::1;;;;;;;;;;;1139:178:::0;:::o;2426:187:32:-;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:32;;;-1:-1:-1;;;;;;2534:17:32;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;1359:130::-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:32;734:10:61;1422:23:32;1414:68;;;;-1:-1:-1;;;1414:68:32;;4764:2:137;1414:68:32;;;4746:21:137;;;4783:18;;;4776:30;4842:34;4822:18;;;4815:62;4894:18;;1414:68:32;4562:356:137;1501:153:33;1590:13;1583:20;;-1:-1:-1;;;;;;1583:20:33;;;1613:34;1638:8;1613:24;:34::i;222:173:137:-;290:20;;-1:-1:-1;;;;;339:31:137;;329:42;;319:70;;385:1;382;375:12;319:70;222:173;;;:::o;400:160::-;465:20;;521:13;;514:21;504:32;;494:60;;550:1;547;540:12;565:322;639:6;647;655;708:2;696:9;687:7;683:23;679:32;676:52;;;724:1;721;714:12;676:52;747:29;766:9;747:29;:::i;:::-;737:39;;823:2;812:9;808:18;795:32;785:42;;846:35;877:2;866:9;862:18;846:35;:::i;:::-;836:45;;565:322;;;;;:::o;892:254::-;960:6;968;1021:2;1009:9;1000:7;996:23;992:32;989:52;;;1037:1;1034;1027:12;989:52;1060:29;1079:9;1060:29;:::i;:::-;1050:39;1136:2;1121:18;;;;1108:32;;-1:-1:-1;;;892:254:137:o;1343:127::-;1404:10;1399:3;1395:20;1392:1;1385:31;1435:4;1432:1;1425:15;1459:4;1456:1;1449:15;1475:275;1546:2;1540:9;1611:2;1592:13;;-1:-1:-1;;1588:27:137;1576:40;;1646:18;1631:34;;1667:22;;;1628:62;1625:88;;;1693:18;;:::i;:::-;1729:2;1722:22;1475:275;;-1:-1:-1;1475:275:137:o;1755:183::-;1815:4;1848:18;1840:6;1837:30;1834:56;;;1870:18;;:::i;:::-;-1:-1:-1;1915:1:137;1911:14;1927:4;1907:25;;1755:183::o;1943:662::-;1997:5;2050:3;2043:4;2035:6;2031:17;2027:27;2017:55;;2068:1;2065;2058:12;2017:55;2104:6;2091:20;2130:4;2154:60;2170:43;2210:2;2170:43;:::i;:::-;2154:60;:::i;:::-;2248:15;;;2334:1;2330:10;;;;2318:23;;2314:32;;;2279:12;;;;2358:15;;;2355:35;;;2386:1;2383;2376:12;2355:35;2422:2;2414:6;2410:15;2434:142;2450:6;2445:3;2442:15;2434:142;;;2516:17;;2504:30;;2554:12;;;;2467;;2434:142;;;-1:-1:-1;2594:5:137;1943:662;-1:-1:-1;;;;;;1943:662:137:o;2610:1214::-;2734:6;2742;2750;2803:2;2791:9;2782:7;2778:23;2774:32;2771:52;;;2819:1;2816;2809:12;2771:52;2859:9;2846:23;2888:18;2929:2;2921:6;2918:14;2915:34;;;2945:1;2942;2935:12;2915:34;2983:6;2972:9;2968:22;2958:32;;3028:7;3021:4;3017:2;3013:13;3009:27;2999:55;;3050:1;3047;3040:12;2999:55;3086:2;3073:16;3108:4;3132:60;3148:43;3188:2;3148:43;:::i;3132:60::-;3226:15;;;3308:1;3304:10;;;;3296:19;;3292:28;;;3257:12;;;;3332:19;;;3329:39;;;3364:1;3361;3354:12;3329:39;3388:11;;;;3408:148;3424:6;3419:3;3416:15;3408:148;;;3490:23;3509:3;3490:23;:::i;:::-;3478:36;;3441:12;;;;3534;;;;3408:148;;;3575:5;-1:-1:-1;;3618:18:137;;3605:32;;-1:-1:-1;;3649:16:137;;;3646:36;;;3678:1;3675;3668:12;3646:36;;3701:63;3756:7;3745:8;3734:9;3730:24;3701:63;:::i;:::-;3691:73;;;3783:35;3814:2;3803:9;3799:18;3783:35;:::i;3829:186::-;3888:6;3941:2;3929:9;3920:7;3916:23;3912:32;3909:52;;;3957:1;3954;3947:12;3909:52;3980:29;3999:9;3980:29;:::i;:::-;3970:39;3829:186;-1:-1:-1;;;3829:186:137:o;4430:127::-;4491:10;4486:3;4482:20;4479:1;4472:31;4522:4;4519:1;4512:15;4546:4;4543:1;4536:15","linkReferences":{}},"methodIdentifiers":{"acceptOwnership()":"79ba5097","hasTag(address,bytes32)":"d019577a","owner()":"8da5cb5b","pendingOwner()":"e30c3978","renounceOwnership()":"715018a6","setTag(address,bytes32,bool)":"9cd9c520","setTags(address[],bytes32[],bool)":"f12715a1","transferOwnership(address)":"f2fde38b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidInputData\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasTag\",\"type\":\"bool\"}],\"name\":\"TagSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"hasTag\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"_hasTag\",\"type\":\"bool\"}],\"name\":\"setTag\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_tags\",\"type\":\"bytes32[]\"},{\"internalType\":\"bool\",\"name\":\"_hasTag\",\"type\":\"bool\"}],\"name\":\"setTags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"hasTag(address,bytes32)\":{\"details\":\"Return if an address is associated with a tag.\",\"params\":{\"_address\":\"Address that is examined for a `tag`.\",\"tag\":\"Tag that should an `_address` be associated with.\"},\"returns\":{\"_0\":\"True if given address has a tag.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTag(address,bytes32,bool)\":{\"details\":\"Tag can be added or removed via this functions. Only callable by contract owner.\",\"params\":{\"_address\":\"Address to which a tag is set.\",\"_hasTag\":\"Bool value if tag is added or removed.\",\"tag\":\"Tag that is set to an `_address`.\"}},\"setTags(address[],bytes32[],bool)\":{\"details\":\"Tags can be added or removed via this functions. Only callable by contract owner.\",\"params\":{\"_addresses\":\"List of addresses to which tags are set.\",\"_hasTag\":\"Bool value if tags are added or removed.\",\"_tags\":\"List of tags that are set to an `_address`.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"stateVariables\":{\"tags\":{\"details\":\"Mapping of address tags. (contract address => tag => is tagged)\"}},\"title\":\"PWN Hub\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidInputData()\":[{\"notice\":\"Thrown when `PWNHub.setTags` inputs lengths are not equal.\"}]},\"events\":{\"TagSet(address,bytes32,bool)\":{\"notice\":\"Emitted when tag is set for an address.\"}},\"kind\":\"user\",\"methods\":{\"setTag(address,bytes32,bool)\":{\"notice\":\"Set tag to an address.\"},\"setTags(address[],bytes32[],bool)\":{\"notice\":\"Set list of tags to an address.\"}},\"notice\":\"Connects PWN contracts together into protocol via tags.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/hub/PWNHub.sol\":\"PWNHub\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"type":"error","name":"InvalidInputData"},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferStarted","anonymous":false},{"inputs":[{"internalType":"address","name":"previousOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferred","anonymous":false},{"inputs":[{"internalType":"address","name":"_address","type":"address","indexed":true},{"internalType":"bytes32","name":"tag","type":"bytes32","indexed":true},{"internalType":"bool","name":"hasTag","type":"bool","indexed":false}],"type":"event","name":"TagSet","anonymous":false},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"acceptOwnership"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"}],"stateMutability":"view","type":"function","name":"hasTag","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"renounceOwnership"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"},{"internalType":"bool","name":"_hasTag","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setTag"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"internalType":"bytes32[]","name":"_tags","type":"bytes32[]"},{"internalType":"bool","name":"_hasTag","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setTags"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"transferOwnership"}],"devdoc":{"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"hasTag(address,bytes32)":{"details":"Return if an address is associated with a tag.","params":{"_address":"Address that is examined for a `tag`.","tag":"Tag that should an `_address` be associated with."},"returns":{"_0":"True if given address has a tag."}},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."},"setTag(address,bytes32,bool)":{"details":"Tag can be added or removed via this functions. Only callable by contract owner.","params":{"_address":"Address to which a tag is set.","_hasTag":"Bool value if tag is added or removed.","tag":"Tag that is set to an `_address`."}},"setTags(address[],bytes32[],bool)":{"details":"Tags can be added or removed via this functions. Only callable by contract owner.","params":{"_addresses":"List of addresses to which tags are set.","_hasTag":"Bool value if tags are added or removed.","_tags":"List of tags that are set to an `_address`."}},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner."}},"version":1},"userdoc":{"kind":"user","methods":{"setTag(address,bytes32,bool)":{"notice":"Set tag to an address."},"setTags(address[],bytes32[],bool)":{"notice":"Set list of tags to an address."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/hub/PWNHub.sol":"PWNHub"},"evmVersion":"london","libraries":{}},"sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"}},"version":1},"id":81} \ No newline at end of file +[ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "acceptOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasTag", + "inputs": [ + { + "name": "_address", + "type": "address", + "internalType": "address" + }, + { + "name": "tag", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pendingOwner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setTag", + "inputs": [ + { + "name": "_address", + "type": "address", + "internalType": "address" + }, + { + "name": "tag", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "_hasTag", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setTags", + "inputs": [ + { + "name": "_addresses", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "_tags", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "_hasTag", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "OwnershipTransferStarted", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TagSet", + "inputs": [ + { + "name": "_address", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tag", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "hasTag", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "InvalidInputData", + "inputs": [] + } +] \ No newline at end of file diff --git a/packages/subgraph/abis/LoanToken.json b/packages/subgraph/abis/LoanToken.json index 63cd0c73..04e4d181 100644 --- a/packages/subgraph/abis/LoanToken.json +++ b/packages/subgraph/abis/LoanToken.json @@ -1 +1,292 @@ -{"abi":[{"type":"constructor","inputs":[{"name":"_hub","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"approve","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"balanceOf","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"burn","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"getApproved","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getStateFingerprint","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"hub","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNHub"}],"stateMutability":"view"},{"type":"function","name":"isApprovedForAll","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"lastLoanId","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"loanContract","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"mint","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"ownerOf","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"safeTransferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"safeTransferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setApprovalForAll","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"tokenURI","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"transferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ApprovalForAll","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"LOANBurned","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"LOANMinted","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"loanContract","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"CallerMissingHubTag","inputs":[{"name":"tag","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidLoanContractCaller","inputs":[]}],"bytecode":{"object":"0x60a06040523480156200001157600080fd5b5060405162001893380380620018938339810160408190526200003491620000a7565b60405180604001604052806008815260200167282ba7102627a0a760c11b815250604051806040016040528060048152602001632627a0a760e11b81525081600090816200008391906200017e565b5060016200009282826200017e565b5050506001600160a01b03166080526200024a565b600060208284031215620000ba57600080fd5b81516001600160a01b0381168114620000d257600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200010457607f821691505b6020821081036200012557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200017957600081815260208120601f850160051c81016020861015620001545750805b601f850160051c820191505b81811015620001755782815560010162000160565b5050505b505050565b81516001600160401b038111156200019a576200019a620000d9565b620001b281620001ab8454620000ef565b846200012b565b602080601f831160018114620001ea5760008415620001d15750858301515b600019600386901b1c1916600185901b17855562000175565b600085815260208120601f198616915b828110156200021b57888601518255948401946001909101908401620001fa565b50858210156200023a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516116266200026d600039600081816101bb015261067f01526116266000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806368be92b4116100ad578063a22cb46511610071578063a22cb46514610284578063b88d4fde14610297578063c87b56dd146102aa578063e985e9c5146102bd578063f5112315146102f957600080fd5b806368be92b4146102165780636a6278421461022d57806370a082311461024057806395d89b4114610253578063a00d21fc1461025b57600080fd5b806323b872dd116100f457806323b872dd146101a3578063365a86fc146101b657806342842e0e146101dd57806342966c68146101f05780636352211e1461020357600080fd5b806301ffc9a71461012657806306fdde031461014e578063081812fc14610163578063095ea7b31461018e575b600080fd5b6101396101343660046110dc565b61030c565b60405190151581526020015b60405180910390f35b610156610338565b6040516101459190611149565b61017661017136600461115c565b6103ca565b6040516001600160a01b039091168152602001610145565b6101a161019c366004611191565b6103f1565b005b6101a16101b13660046111bb565b61050b565b6101767f000000000000000000000000000000000000000000000000000000000000000081565b6101a16101eb3660046111bb565b61053c565b6101a16101fe36600461115c565b610557565b61017661021136600461115c565b6105e1565b61021f60065481565b604051908152602001610145565b61021f61023b3660046111f7565b610641565b61021f61024e3660046111f7565b6107ac565b610156610832565b61017661026936600461115c565b6007602052600090815260409020546001600160a01b031681565b6101a1610292366004611220565b610841565b6101a16102a53660046112c6565b610850565b6101566102b836600461115c565b610888565b6101396102cb366004611371565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61021f61030736600461115c565b61090b565b6000610317826109a1565b8061033257506001600160e01b0319821663f511231560e01b145b92915050565b606060008054610347906113a4565b80601f0160208091040260200160405190810160405280929190818152602001828054610373906113a4565b80156103c05780601f10610395576101008083540402835291602001916103c0565b820191906000526020600020905b8154815290600101906020018083116103a357829003601f168201915b5050505050905090565b60006103d5826109f1565b506000908152600460205260409020546001600160a01b031690565b60006103fc826105e1565b9050806001600160a01b0316836001600160a01b03160361046e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061048a575061048a81336102cb565b6104fc5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610465565b6105068383610a53565b505050565b6105153382610ac1565b6105315760405162461bcd60e51b8152600401610465906113de565b610506838383610b40565b61050683838360405180602001604052806000815250610850565b6000818152600760205260409020546001600160a01b0316331461058e576040516374768c4960e11b815260040160405180910390fd5b600081815260076020526040902080546001600160a01b03191690556105b381610ca4565b60405181907f56f7da88d3aa2a8ad74b71a5b449a66a643193815eace8bbd6b089d4bc18294b90600090a250565b6000818152600260205260408120546001600160a01b0316806103325760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b60405163680cabbd60e11b81523360048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d019577a90604401602060405180830381865afa1580156106ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f2919061142b565b6107315760405163f8932b2d60e01b81527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946004820152602401610465565b60066000815461074090611448565b9182905550600081815260076020526040902080546001600160a01b03191633179055905061076f8282610d39565b6040516001600160a01b03831690339083907f2ca529bede83c064afd9331357a1ce320271c9c7ceda28ac31472d76f7aff53090600090a4919050565b60006001600160a01b0382166108165760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610465565b506001600160a01b031660009081526003602052604090205490565b606060018054610347906113a4565b61084c338383610ec4565b5050565b61085a3383610ac1565b6108765760405162461bcd60e51b8152600401610465906113de565b61088284848484610f92565b50505050565b6060610893826109f1565b60008281526007602052604080822054815163111d8a1560e01b815291516001600160a01b039091169263111d8a1592600480820193918290030181865afa1580156108e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610332919081019061146f565b6000818152600760205260408120546001600160a01b0316806109315750600092915050565b60405163f511231560e01b8152600481018490526001600160a01b0382169063f511231590602401602060405180830381865afa158015610976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099a91906114e6565b9392505050565b60006001600160e01b031982166380ac58cd60e01b14806109d257506001600160e01b03198216635b5e139f60e01b145b8061033257506301ffc9a760e01b6001600160e01b0319831614610332565b6000818152600260205260409020546001600160a01b0316610a505760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610a88826105e1565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610acd836105e1565b9050806001600160a01b0316846001600160a01b03161480610b1457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610b385750836001600160a01b0316610b2d846103ca565b6001600160a01b0316145b949350505050565b826001600160a01b0316610b53826105e1565b6001600160a01b031614610b795760405162461bcd60e51b8152600401610465906114ff565b6001600160a01b038216610bdb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610465565b826001600160a01b0316610bee826105e1565b6001600160a01b031614610c145760405162461bcd60e51b8152600401610465906114ff565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610caf826105e1565b9050610cba826105e1565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b038216610d8f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610465565b6000818152600260205260409020546001600160a01b031615610df45760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6000818152600260205260409020546001600160a01b031615610e595760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610f255760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610465565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610f9d848484610b40565b610fa984848484610fc5565b6108825760405162461bcd60e51b815260040161046590611544565b60006001600160a01b0384163b156110bb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611009903390899088908890600401611596565b6020604051808303816000875af1925050508015611044575060408051601f3d908101601f19168201909252611041918101906115d3565b60015b6110a1573d808015611072576040519150601f19603f3d011682016040523d82523d6000602084013e611077565b606091505b5080516000036110995760405162461bcd60e51b815260040161046590611544565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610b38565b506001949350505050565b6001600160e01b031981168114610a5057600080fd5b6000602082840312156110ee57600080fd5b813561099a816110c6565b60005b838110156111145781810151838201526020016110fc565b50506000910152565b600081518084526111358160208601602086016110f9565b601f01601f19169290920160200192915050565b60208152600061099a602083018461111d565b60006020828403121561116e57600080fd5b5035919050565b80356001600160a01b038116811461118c57600080fd5b919050565b600080604083850312156111a457600080fd5b6111ad83611175565b946020939093013593505050565b6000806000606084860312156111d057600080fd5b6111d984611175565b92506111e760208501611175565b9150604084013590509250925092565b60006020828403121561120957600080fd5b61099a82611175565b8015158114610a5057600080fd5b6000806040838503121561123357600080fd5b61123c83611175565b9150602083013561124c81611212565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561129657611296611257565b604052919050565b600067ffffffffffffffff8211156112b8576112b8611257565b50601f01601f191660200190565b600080600080608085870312156112dc57600080fd5b6112e585611175565b93506112f360208601611175565b925060408501359150606085013567ffffffffffffffff81111561131657600080fd5b8501601f8101871361132757600080fd5b803561133a6113358261129e565b61126d565b81815288602083850101111561134f57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561138457600080fd5b61138d83611175565b915061139b60208401611175565b90509250929050565b600181811c908216806113b857607f821691505b6020821081036113d857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60006020828403121561143d57600080fd5b815161099a81611212565b60006001820161146857634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121561148157600080fd5b815167ffffffffffffffff81111561149857600080fd5b8201601f810184136114a957600080fd5b80516114b76113358261129e565b8181528560208385010111156114cc57600080fd5b6114dd8260208301602086016110f9565b95945050505050565b6000602082840312156114f857600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906115c99083018461111d565b9695505050505050565b6000602082840312156115e557600080fd5b815161099a816110c656fea2646970667358221220b7de9ec72201d73c775ea864f50f9ddf2db4959b34b068baf1f629cef092f01864736f6c63430008100033","sourceMap":"635:5123:100:-:0;;;2752:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1390:113:56;;;;;;;;;;;;;-1:-1:-1;;;1390:113:56;;;;;;;;;;;;;;;;-1:-1:-1;;;1390:113:56;;;1464:5;1456;:13;;;;;;:::i;:::-;-1:-1:-1;1479:7:56;:17;1489:7;1479;:17;:::i;:::-;-1:-1:-1;;;;;;;;2815:18:100::1;;::::0;635:5123;;14:290:137;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;179:16;;-1:-1:-1;;;;;224:31:137;;214:42;;204:70;;270:1;267;260:12;204:70;293:5;14:290;-1:-1:-1;;;14:290:137:o;309:127::-;370:10;365:3;361:20;358:1;351:31;401:4;398:1;391:15;425:4;422:1;415:15;441:380;520:1;516:12;;;;563;;;584:61;;638:4;630:6;626:17;616:27;;584:61;691:2;683:6;680:14;660:18;657:38;654:161;;737:10;732:3;728:20;725:1;718:31;772:4;769:1;762:15;800:4;797:1;790:15;654:161;;441:380;;;:::o;952:545::-;1054:2;1049:3;1046:11;1043:448;;;1090:1;1115:5;1111:2;1104:17;1160:4;1156:2;1146:19;1230:2;1218:10;1214:19;1211:1;1207:27;1201:4;1197:38;1266:4;1254:10;1251:20;1248:47;;;-1:-1:-1;1289:4:137;1248:47;1344:2;1339:3;1335:12;1332:1;1328:20;1322:4;1318:31;1308:41;;1399:82;1417:2;1410:5;1407:13;1399:82;;;1462:17;;;1443:1;1432:13;1399:82;;;1403:3;;;1043:448;952:545;;;:::o;1673:1352::-;1793:10;;-1:-1:-1;;;;;1815:30:137;;1812:56;;;1848:18;;:::i;:::-;1877:97;1967:6;1927:38;1959:4;1953:11;1927:38;:::i;:::-;1921:4;1877:97;:::i;:::-;2029:4;;2093:2;2082:14;;2110:1;2105:663;;;;2812:1;2829:6;2826:89;;;-1:-1:-1;2881:19:137;;;2875:26;2826:89;-1:-1:-1;;1630:1:137;1626:11;;;1622:24;1618:29;1608:40;1654:1;1650:11;;;1605:57;2928:81;;2075:944;;2105:663;899:1;892:14;;;936:4;923:18;;-1:-1:-1;;2141:20:137;;;2259:236;2273:7;2270:1;2267:14;2259:236;;;2362:19;;;2356:26;2341:42;;2454:27;;;;2422:1;2410:14;;;;2289:19;;2259:236;;;2263:3;2523:6;2514:7;2511:19;2508:201;;;2584:19;;;2578:26;-1:-1:-1;;2667:1:137;2663:14;;;2679:3;2659:24;2655:37;2651:42;2636:58;2621:74;;2508:201;-1:-1:-1;;;;;2755:1:137;2739:14;;;2735:22;2722:36;;-1:-1:-1;1673:1352:137:o;:::-;635:5123:100;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106101215760003560e01c806368be92b4116100ad578063a22cb46511610071578063a22cb46514610284578063b88d4fde14610297578063c87b56dd146102aa578063e985e9c5146102bd578063f5112315146102f957600080fd5b806368be92b4146102165780636a6278421461022d57806370a082311461024057806395d89b4114610253578063a00d21fc1461025b57600080fd5b806323b872dd116100f457806323b872dd146101a3578063365a86fc146101b657806342842e0e146101dd57806342966c68146101f05780636352211e1461020357600080fd5b806301ffc9a71461012657806306fdde031461014e578063081812fc14610163578063095ea7b31461018e575b600080fd5b6101396101343660046110dc565b61030c565b60405190151581526020015b60405180910390f35b610156610338565b6040516101459190611149565b61017661017136600461115c565b6103ca565b6040516001600160a01b039091168152602001610145565b6101a161019c366004611191565b6103f1565b005b6101a16101b13660046111bb565b61050b565b6101767f000000000000000000000000000000000000000000000000000000000000000081565b6101a16101eb3660046111bb565b61053c565b6101a16101fe36600461115c565b610557565b61017661021136600461115c565b6105e1565b61021f60065481565b604051908152602001610145565b61021f61023b3660046111f7565b610641565b61021f61024e3660046111f7565b6107ac565b610156610832565b61017661026936600461115c565b6007602052600090815260409020546001600160a01b031681565b6101a1610292366004611220565b610841565b6101a16102a53660046112c6565b610850565b6101566102b836600461115c565b610888565b6101396102cb366004611371565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61021f61030736600461115c565b61090b565b6000610317826109a1565b8061033257506001600160e01b0319821663f511231560e01b145b92915050565b606060008054610347906113a4565b80601f0160208091040260200160405190810160405280929190818152602001828054610373906113a4565b80156103c05780601f10610395576101008083540402835291602001916103c0565b820191906000526020600020905b8154815290600101906020018083116103a357829003601f168201915b5050505050905090565b60006103d5826109f1565b506000908152600460205260409020546001600160a01b031690565b60006103fc826105e1565b9050806001600160a01b0316836001600160a01b03160361046e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061048a575061048a81336102cb565b6104fc5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610465565b6105068383610a53565b505050565b6105153382610ac1565b6105315760405162461bcd60e51b8152600401610465906113de565b610506838383610b40565b61050683838360405180602001604052806000815250610850565b6000818152600760205260409020546001600160a01b0316331461058e576040516374768c4960e11b815260040160405180910390fd5b600081815260076020526040902080546001600160a01b03191690556105b381610ca4565b60405181907f56f7da88d3aa2a8ad74b71a5b449a66a643193815eace8bbd6b089d4bc18294b90600090a250565b6000818152600260205260408120546001600160a01b0316806103325760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b60405163680cabbd60e11b81523360048201527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc560359460248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d019577a90604401602060405180830381865afa1580156106ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f2919061142b565b6107315760405163f8932b2d60e01b81527f9e56ea094d7a53440eef11fa42b63159fbf703b4ee579494a6ae85afc56035946004820152602401610465565b60066000815461074090611448565b9182905550600081815260076020526040902080546001600160a01b03191633179055905061076f8282610d39565b6040516001600160a01b03831690339083907f2ca529bede83c064afd9331357a1ce320271c9c7ceda28ac31472d76f7aff53090600090a4919050565b60006001600160a01b0382166108165760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610465565b506001600160a01b031660009081526003602052604090205490565b606060018054610347906113a4565b61084c338383610ec4565b5050565b61085a3383610ac1565b6108765760405162461bcd60e51b8152600401610465906113de565b61088284848484610f92565b50505050565b6060610893826109f1565b60008281526007602052604080822054815163111d8a1560e01b815291516001600160a01b039091169263111d8a1592600480820193918290030181865afa1580156108e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610332919081019061146f565b6000818152600760205260408120546001600160a01b0316806109315750600092915050565b60405163f511231560e01b8152600481018490526001600160a01b0382169063f511231590602401602060405180830381865afa158015610976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099a91906114e6565b9392505050565b60006001600160e01b031982166380ac58cd60e01b14806109d257506001600160e01b03198216635b5e139f60e01b145b8061033257506301ffc9a760e01b6001600160e01b0319831614610332565b6000818152600260205260409020546001600160a01b0316610a505760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610465565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610a88826105e1565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610acd836105e1565b9050806001600160a01b0316846001600160a01b03161480610b1457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610b385750836001600160a01b0316610b2d846103ca565b6001600160a01b0316145b949350505050565b826001600160a01b0316610b53826105e1565b6001600160a01b031614610b795760405162461bcd60e51b8152600401610465906114ff565b6001600160a01b038216610bdb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610465565b826001600160a01b0316610bee826105e1565b6001600160a01b031614610c145760405162461bcd60e51b8152600401610465906114ff565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610caf826105e1565b9050610cba826105e1565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b038216610d8f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610465565b6000818152600260205260409020546001600160a01b031615610df45760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6000818152600260205260409020546001600160a01b031615610e595760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610465565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610f255760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610465565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610f9d848484610b40565b610fa984848484610fc5565b6108825760405162461bcd60e51b815260040161046590611544565b60006001600160a01b0384163b156110bb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611009903390899088908890600401611596565b6020604051808303816000875af1925050508015611044575060408051601f3d908101601f19168201909252611041918101906115d3565b60015b6110a1573d808015611072576040519150601f19603f3d011682016040523d82523d6000602084013e611077565b606091505b5080516000036110995760405162461bcd60e51b815260040161046590611544565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610b38565b506001949350505050565b6001600160e01b031981168114610a5057600080fd5b6000602082840312156110ee57600080fd5b813561099a816110c6565b60005b838110156111145781810151838201526020016110fc565b50506000910152565b600081518084526111358160208601602086016110f9565b601f01601f19169290920160200192915050565b60208152600061099a602083018461111d565b60006020828403121561116e57600080fd5b5035919050565b80356001600160a01b038116811461118c57600080fd5b919050565b600080604083850312156111a457600080fd5b6111ad83611175565b946020939093013593505050565b6000806000606084860312156111d057600080fd5b6111d984611175565b92506111e760208501611175565b9150604084013590509250925092565b60006020828403121561120957600080fd5b61099a82611175565b8015158114610a5057600080fd5b6000806040838503121561123357600080fd5b61123c83611175565b9150602083013561124c81611212565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561129657611296611257565b604052919050565b600067ffffffffffffffff8211156112b8576112b8611257565b50601f01601f191660200190565b600080600080608085870312156112dc57600080fd5b6112e585611175565b93506112f360208601611175565b925060408501359150606085013567ffffffffffffffff81111561131657600080fd5b8501601f8101871361132757600080fd5b803561133a6113358261129e565b61126d565b81815288602083850101111561134f57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561138457600080fd5b61138d83611175565b915061139b60208401611175565b90509250929050565b600181811c908216806113b857607f821691505b6020821081036113d857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60006020828403121561143d57600080fd5b815161099a81611212565b60006001820161146857634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121561148157600080fd5b815167ffffffffffffffff81111561149857600080fd5b8201601f810184136114a957600080fd5b80516114b76113358261129e565b8181528560208385010111156114cc57600080fd5b6114dd8260208301602086016110f9565b95945050505050565b6000602082840312156114f857600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906115c99083018461111d565b9695505050505050565b6000602082840312156115e557600080fd5b815161099a816110c656fea2646970667358221220b7de9ec72201d73c775ea864f50f9ddf2db4959b34b068baf1f629cef092f01864736f6c63430008100033","sourceMap":"635:5123:100:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5547:208;;;;;;:::i;:::-;;:::i;:::-;;;565:14:137;;558:22;540:41;;528:2;513:18;5547:208:100;;;;;;;;2471:98:56;;;:::i;:::-;;;;;;;:::i;3935:167::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:137;;;1679:51;;1667:2;1652:18;3935:167:56;1533:203:137;3468:406:56;;;;;;:::i;:::-;;:::i;:::-;;4612:296;;;;;;:::i;:::-;;:::i;881:27:100:-;;;;;4974:149:56;;;;;;:::i;:::-;;:::i;3837:236:100:-;;;;;;:::i;:::-;;:::i;2190:219:56:-;;;;;;:::i;:::-;;:::i;1009:25:100:-;;;;;;;;;2881::137;;;2869:2;2854:18;1009:25:100;2735:177:137;3309:241:100;;;;;;:::i;:::-;;:::i;1929:204:56:-;;;;;;:::i;:::-;;:::i;2633:102::-;;;:::i;1137:48:100:-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1137:48:100;;;4169:153:56;;;;;;:::i;:::-;;:::i;5189:276::-;;;;;;:::i;:::-;;:::i;4493:211:100:-;;;;;;:::i;:::-;;:::i;4388:162:56:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4508:25:56;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4388:162;4977:300:100;;;;;;:::i;:::-;;:::i;5547:208::-;5632:4;5655:36;5679:11;5655:23;:36::i;:::-;:93;;;-1:-1:-1;;;;;;;5707:41:100;;-1:-1:-1;;;5707:41:100;5655:93;5648:100;5547:208;-1:-1:-1;;5547:208:100:o;2471:98:56:-;2525:13;2557:5;2550:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2471:98;:::o;3935:167::-;4011:7;4030:23;4045:7;4030:14;:23::i;:::-;-1:-1:-1;4071:24:56;;;;:15;:24;;;;;;-1:-1:-1;;;;;4071:24:56;;3935:167::o;3468:406::-;3548:13;3564:23;3579:7;3564:14;:23::i;:::-;3548:39;;3611:5;-1:-1:-1;;;;;3605:11:56;:2;-1:-1:-1;;;;;3605:11:56;;3597:57;;;;-1:-1:-1;;;3597:57:56;;6081:2:137;3597:57:56;;;6063:21:137;6120:2;6100:18;;;6093:30;6159:34;6139:18;;;6132:62;-1:-1:-1;;;6210:18:137;;;6203:31;6251:19;;3597:57:56;;;;;;;;;734:10:61;-1:-1:-1;;;;;3686:21:56;;;;:62;;-1:-1:-1;3711:37:56;3728:5;734:10:61;4388:162:56;:::i;3711:37::-;3665:170;;;;-1:-1:-1;;;3665:170:56;;6483:2:137;3665:170:56;;;6465:21:137;6522:2;6502:18;;;6495:30;6561:34;6541:18;;;6534:62;6632:31;6612:18;;;6605:59;6681:19;;3665:170:56;6281:425:137;3665:170:56;3846:21;3855:2;3859:7;3846:8;:21::i;:::-;3538:336;3468:406;;:::o;4612:296::-;4771:41;734:10:61;4804:7:56;4771:18;:41::i;:::-;4763:99;;;;-1:-1:-1;;;4763:99:56;;;;;;;:::i;:::-;4873:28;4883:4;4889:2;4893:7;4873:9;:28::i;4974:149::-;5077:39;5094:4;5100:2;5104:7;5077:39;;;;;;;;;;;;:16;:39::i;3837:236:100:-;3890:20;;;;:12;:20;;;;;;-1:-1:-1;;;;;3890:20:100;3914:10;3890:34;3886:86;;3945:27;;-1:-1:-1;;;3945:27:100;;;;;;;;;;;3886:86;3990:20;;;;:12;:20;;;;;3983:27;;-1:-1:-1;;;;;;3983:27:100;;;4020:13;4003:6;4020:5;:13::i;:::-;4048:18;;4059:6;;4048:18;;;;;3837:236;:::o;2190:219:56:-;2262:7;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;;2324:56;;;;-1:-1:-1;;;2324:56:56;;7327:2:137;2324:56:56;;;7309:21:137;7366:2;7346:18;;;7339:30;-1:-1:-1;;;7385:18:137;;;7378:54;7449:18;;2324:56:56;7125:348:137;3309:241:100;2406:46;;-1:-1:-1;;;2406:46:100;;2417:10;2406:46;;;7652:51:137;266:28:82;7719:18:137;;;7712:34;3371:14:100;;2406:3;-1:-1:-1;;;;;2406:10:100;;;;7625:18:137;;2406:46:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2401:124;;2473:52;;-1:-1:-1;;;2473:52:100;;266:28:82;2473:52:100;;;2881:25:137;2854:18;;2473:52:100;2735:177:137;2401:124:100;3408:10:::1;;3406:12;;;;;:::i;:::-;::::0;;;;-1:-1:-1;3428:20:100::1;::::0;;;:12:::1;:20;::::0;;;;:33;;-1:-1:-1;;;;;;3428:33:100::1;3451:10;3428:33;::::0;;3406:12;-1:-1:-1;3471:20:100::1;3477:5:::0;3406:12;3471:5:::1;:20::i;:::-;3506:37;::::0;-1:-1:-1;;;;;3506:37:100;::::1;::::0;3525:10:::1;::::0;3517:6;;3506:37:::1;::::0;;;::::1;3309:241:::0;;;:::o;1929:204:56:-;2001:7;-1:-1:-1;;;;;2028:19:56;;2020:73;;;;-1:-1:-1;;;2020:73:56;;8446:2:137;2020:73:56;;;8428:21:137;8485:2;8465:18;;;8458:30;8524:34;8504:18;;;8497:62;-1:-1:-1;;;8575:18:137;;;8568:39;8624:19;;2020:73:56;8244:405:137;2020:73:56;-1:-1:-1;;;;;;2110:16:56;;;;;:9;:16;;;;;;;1929:204::o;2633:102::-;2689:13;2721:7;2714:14;;;;;:::i;4169:153::-;4263:52;734:10:61;4296:8:56;4306;4263:18;:52::i;:::-;4169:153;;:::o;5189:276::-;5319:41;734:10:61;5352:7:56;5319:18;:41::i;:::-;5311:99;;;;-1:-1:-1;;;5311:99:56;;;;;;;:::i;:::-;5420:38;5434:4;5440:2;5444:7;5453:4;5420:13;:38::i;:::-;5189:276;;;;:::o;4493:211:100:-;4566:13;4591:23;4606:7;4591:14;:23::i;:::-;4657:21;;;;:12;:21;;;;;;;4632:65;;-1:-1:-1;;;4632:65:100;;;;-1:-1:-1;;;;;4657:21:100;;;;4632:63;;:65;;;;;;;;;;;4657:21;4632:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4632:65:100;;;;;;;;;;;;:::i;4977:300::-;5063:7;5106:21;;;:12;:21;;;;;;-1:-1:-1;;;;;5106:21:100;;5138:62;;-1:-1:-1;5198:1:100;;4977:300;-1:-1:-1;;4977:300:100:o;5138:62::-;5218:52;;-1:-1:-1;;;5218:52:100;;;;;2881:25:137;;;-1:-1:-1;;;;;5218:43:100;;;;;2854:18:137;;5218:52:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5211:59;4977:300;-1:-1:-1;;;4977:300:100:o;1570::56:-;1672:4;-1:-1:-1;;;;;;1707:40:56;;-1:-1:-1;;;1707:40:56;;:104;;-1:-1:-1;;;;;;;1763:48:56;;-1:-1:-1;;;1763:48:56;1707:104;:156;;;-1:-1:-1;;;;;;;;;;937:40:67;;;1827:36:56;829:155:67;13240:133:56;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;13313:53;;;;-1:-1:-1;;;13313:53:56;;7327:2:137;13313:53:56;;;7309:21:137;7366:2;7346:18;;;7339:30;-1:-1:-1;;;7385:18:137;;;7378:54;7449:18;;13313:53:56;7125:348:137;13313:53:56;13240:133;:::o;12572:171::-;12646:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;12646:29:56;-1:-1:-1;;;;;12646:29:56;;;;;;;;:24;;12699:23;12646:24;12699:14;:23::i;:::-;-1:-1:-1;;;;;12690:46:56;;;;;;;;;;;12572:171;;:::o;7404:261::-;7497:4;7513:13;7529:23;7544:7;7529:14;:23::i;:::-;7513:39;;7581:5;-1:-1:-1;;;;;7570:16:56;:7;-1:-1:-1;;;;;7570:16:56;;:52;;;-1:-1:-1;;;;;;4508:25:56;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7590:32;7570:87;;;;7650:7;-1:-1:-1;;;;;7626:31:56;:20;7638:7;7626:11;:20::i;:::-;-1:-1:-1;;;;;7626:31:56;;7570:87;7562:96;7404:261;-1:-1:-1;;;;7404:261:56:o;11257:1203::-;11381:4;-1:-1:-1;;;;;11354:31:56;:23;11369:7;11354:14;:23::i;:::-;-1:-1:-1;;;;;11354:31:56;;11346:81;;;;-1:-1:-1;;;11346:81:56;;;;;;;:::i;:::-;-1:-1:-1;;;;;11445:16:56;;11437:65;;;;-1:-1:-1;;;11437:65:56;;10104:2:137;11437:65:56;;;10086:21:137;10143:2;10123:18;;;10116:30;10182:34;10162:18;;;10155:62;-1:-1:-1;;;10233:18:137;;;10226:34;10277:19;;11437:65:56;9902:400:137;11437:65:56;11682:4;-1:-1:-1;;;;;11655:31:56;:23;11670:7;11655:14;:23::i;:::-;-1:-1:-1;;;;;11655:31:56;;11647:81;;;;-1:-1:-1;;;11647:81:56;;;;;;;:::i;:::-;11797:24;;;;:15;:24;;;;;;;;11790:31;;-1:-1:-1;;;;;;11790:31:56;;;;;;-1:-1:-1;;;;;12265:15:56;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;12265:20:56;;;12299:13;;;;;;;;;:18;;11790:31;12299:18;;;12337:16;;;:7;:16;;;;;;:21;;;;;;;;;;12374:27;;11813:7;;12374:27;;;3538:336;3468:406;;:::o;10171:762::-;10230:13;10246:23;10261:7;10246:14;:23::i;:::-;10230:39;;10441:23;10456:7;10441:14;:23::i;:::-;10509:24;;;;:15;:24;;;;;;;;10502:31;;-1:-1:-1;;;;;;10502:31:56;;;;;;-1:-1:-1;;;;;10749:16:56;;;;;:9;:16;;;;;:21;;-1:-1:-1;;10749:21:56;;;10797:16;;;:7;:16;;;;;;10790:23;;;;;;;10829:36;10433:31;;-1:-1:-1;10525:7:56;;10829:36;;10509:24;;10829:36;4169:153;;:::o;8925:920::-;-1:-1:-1;;;;;9004:16:56;;8996:61;;;;-1:-1:-1;;;8996:61:56;;10509:2:137;8996:61:56;;;10491:21:137;;;10528:18;;;10521:30;10587:34;10567:18;;;10560:62;10639:18;;8996:61:56;10307:356:137;8996:61:56;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;7208:31;9067:58;;;;-1:-1:-1;;;9067:58:56;;10870:2:137;9067:58:56;;;10852:21:137;10909:2;10889:18;;;10882:30;10948;10928:18;;;10921:58;10996:18;;9067:58:56;10668:352:137;9067:58:56;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:56;7208:31;9271:58;;;;-1:-1:-1;;;9271:58:56;;10870:2:137;9271:58:56;;;10852:21:137;10909:2;10889:18;;;10882:30;10948;10928:18;;;10921:58;10996:18;;9271:58:56;10668:352:137;9271:58:56;-1:-1:-1;;;;;9671:13:56;;;;;;:9;:13;;;;;;;;:18;;9688:1;9671:18;;;9710:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9710:21:56;;;;;9747:33;9718:7;;9671:13;;9747:33;;9671:13;;9747:33;4169:153;;:::o;12879:277::-;12999:8;-1:-1:-1;;;;;12990:17:56;:5;-1:-1:-1;;;;;12990:17:56;;12982:55;;;;-1:-1:-1;;;12982:55:56;;11227:2:137;12982:55:56;;;11209:21:137;11266:2;11246:18;;;11239:30;11305:27;11285:18;;;11278:55;11350:18;;12982:55:56;11025:349:137;12982:55:56;-1:-1:-1;;;;;13047:25:56;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13047:46:56;;;;;;;;;;13108:41;;540::137;;;13108::56;;513:18:137;13108:41:56;;;;;;;12879:277;;;:::o;6326:267::-;6438:28;6448:4;6454:2;6458:7;6438:9;:28::i;:::-;6484:47;6507:4;6513:2;6517:7;6526:4;6484:22;:47::i;:::-;6476:110;;;;-1:-1:-1;;;6476:110:56;;;;;;;:::i;13925:831::-;14074:4;-1:-1:-1;;;;;14094:13:56;;1702:19:60;:23;14090:660:56;;14129:71;;-1:-1:-1;;;14129:71:56;;-1:-1:-1;;;;;14129:36:56;;;;;:71;;734:10:61;;14180:4:56;;14186:7;;14195:4;;14129:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14129:71:56;;;;;;;;-1:-1:-1;;14129:71:56;;;;;;;;;;;;:::i;:::-;;;14125:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14367:6;:13;14384:1;14367:18;14363:321;;14409:60;;-1:-1:-1;;;14409:60:56;;;;;;;:::i;14363:321::-;14636:6;14630:13;14621:6;14617:2;14613:15;14606:38;14125:573;-1:-1:-1;;;;;;14250:51:56;-1:-1:-1;;;14250:51:56;;-1:-1:-1;14243:58:56;;14090:660;-1:-1:-1;14735:4:56;13925:831;;;;;;:::o;14:131:137:-;-1:-1:-1;;;;;;88:32:137;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:137;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:137;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:137:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:137;;1348:180;-1:-1:-1;1348:180:137:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:137;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:137:o;2178:328::-;2255:6;2263;2271;2324:2;2312:9;2303:7;2299:23;2295:32;2292:52;;;2340:1;2337;2330:12;2292:52;2363:29;2382:9;2363:29;:::i;:::-;2353:39;;2411:38;2445:2;2434:9;2430:18;2411:38;:::i;:::-;2401:48;;2496:2;2485:9;2481:18;2468:32;2458:42;;2178:328;;;;;:::o;2917:186::-;2976:6;3029:2;3017:9;3008:7;3004:23;3000:32;2997:52;;;3045:1;3042;3035:12;2997:52;3068:29;3087:9;3068:29;:::i;3108:118::-;3194:5;3187:13;3180:21;3173:5;3170:32;3160:60;;3216:1;3213;3206:12;3231:315;3296:6;3304;3357:2;3345:9;3336:7;3332:23;3328:32;3325:52;;;3373:1;3370;3363:12;3325:52;3396:29;3415:9;3396:29;:::i;:::-;3386:39;;3475:2;3464:9;3460:18;3447:32;3488:28;3510:5;3488:28;:::i;:::-;3535:5;3525:15;;;3231:315;;;;;:::o;3551:127::-;3612:10;3607:3;3603:20;3600:1;3593:31;3643:4;3640:1;3633:15;3667:4;3664:1;3657:15;3683:275;3754:2;3748:9;3819:2;3800:13;;-1:-1:-1;;3796:27:137;3784:40;;3854:18;3839:34;;3875:22;;;3836:62;3833:88;;;3901:18;;:::i;:::-;3937:2;3930:22;3683:275;;-1:-1:-1;3683:275:137:o;3963:186::-;4011:4;4044:18;4036:6;4033:30;4030:56;;;4066:18;;:::i;:::-;-1:-1:-1;4132:2:137;4111:15;-1:-1:-1;;4107:29:137;4138:4;4103:40;;3963:186::o;4154:888::-;4249:6;4257;4265;4273;4326:3;4314:9;4305:7;4301:23;4297:33;4294:53;;;4343:1;4340;4333:12;4294:53;4366:29;4385:9;4366:29;:::i;:::-;4356:39;;4414:38;4448:2;4437:9;4433:18;4414:38;:::i;:::-;4404:48;;4499:2;4488:9;4484:18;4471:32;4461:42;;4554:2;4543:9;4539:18;4526:32;4581:18;4573:6;4570:30;4567:50;;;4613:1;4610;4603:12;4567:50;4636:22;;4689:4;4681:13;;4677:27;-1:-1:-1;4667:55:137;;4718:1;4715;4708:12;4667:55;4754:2;4741:16;4779:48;4795:31;4823:2;4795:31;:::i;:::-;4779:48;:::i;:::-;4850:2;4843:5;4836:17;4890:7;4885:2;4880;4876;4872:11;4868:20;4865:33;4862:53;;;4911:1;4908;4901:12;4862:53;4966:2;4961;4957;4953:11;4948:2;4941:5;4937:14;4924:45;5010:1;5005:2;5000;4993:5;4989:14;4985:23;4978:34;5031:5;5021:15;;;;;4154:888;;;;;;;:::o;5047:260::-;5115:6;5123;5176:2;5164:9;5155:7;5151:23;5147:32;5144:52;;;5192:1;5189;5182:12;5144:52;5215:29;5234:9;5215:29;:::i;:::-;5205:39;;5263:38;5297:2;5286:9;5282:18;5263:38;:::i;:::-;5253:48;;5047:260;;;;;:::o;5494:380::-;5573:1;5569:12;;;;5616;;;5637:61;;5691:4;5683:6;5679:17;5669:27;;5637:61;5744:2;5736:6;5733:14;5713:18;5710:38;5707:161;;5790:10;5785:3;5781:20;5778:1;5771:31;5825:4;5822:1;5815:15;5853:4;5850:1;5843:15;5707:161;;5494:380;;;:::o;6711:409::-;6913:2;6895:21;;;6952:2;6932:18;;;6925:30;6991:34;6986:2;6971:18;;6964:62;-1:-1:-1;;;7057:2:137;7042:18;;7035:43;7110:3;7095:19;;6711:409::o;7757:245::-;7824:6;7877:2;7865:9;7856:7;7852:23;7848:32;7845:52;;;7893:1;7890;7883:12;7845:52;7925:9;7919:16;7944:28;7966:5;7944:28;:::i;8007:232::-;8046:3;8067:17;;;8064:140;;8126:10;8121:3;8117:20;8114:1;8107:31;8161:4;8158:1;8151:15;8189:4;8186:1;8179:15;8064:140;-1:-1:-1;8231:1:137;8220:13;;8007:232::o;8654:648::-;8734:6;8787:2;8775:9;8766:7;8762:23;8758:32;8755:52;;;8803:1;8800;8793:12;8755:52;8836:9;8830:16;8869:18;8861:6;8858:30;8855:50;;;8901:1;8898;8891:12;8855:50;8924:22;;8977:4;8969:13;;8965:27;-1:-1:-1;8955:55:137;;9006:1;9003;8996:12;8955:55;9035:2;9029:9;9060:48;9076:31;9104:2;9076:31;:::i;9060:48::-;9131:2;9124:5;9117:17;9171:7;9166:2;9161;9157;9153:11;9149:20;9146:33;9143:53;;;9192:1;9189;9182:12;9143:53;9205:67;9269:2;9264;9257:5;9253:14;9248:2;9244;9240:11;9205:67;:::i;:::-;9291:5;8654:648;-1:-1:-1;;;;;8654:648:137:o;9307:184::-;9377:6;9430:2;9418:9;9409:7;9405:23;9401:32;9398:52;;;9446:1;9443;9436:12;9398:52;-1:-1:-1;9469:16:137;;9307:184;-1:-1:-1;9307:184:137:o;9496:401::-;9698:2;9680:21;;;9737:2;9717:18;;;9710:30;9776:34;9771:2;9756:18;;9749:62;-1:-1:-1;;;9842:2:137;9827:18;;9820:35;9887:3;9872:19;;9496:401::o;11379:414::-;11581:2;11563:21;;;11620:2;11600:18;;;11593:30;11659:34;11654:2;11639:18;;11632:62;-1:-1:-1;;;11725:2:137;11710:18;;11703:48;11783:3;11768:19;;11379:414::o;11798:489::-;-1:-1:-1;;;;;12067:15:137;;;12049:34;;12119:15;;12114:2;12099:18;;12092:43;12166:2;12151:18;;12144:34;;;12214:3;12209:2;12194:18;;12187:31;;;11992:4;;12235:46;;12261:19;;12253:6;12235:46;:::i;:::-;12227:54;11798:489;-1:-1:-1;;;;;;11798:489:137:o;12292:249::-;12361:6;12414:2;12402:9;12393:7;12389:23;12385:32;12382:52;;;12430:1;12427;12420:12;12382:52;12462:9;12456:16;12481:30;12505:5;12481:30;:::i","linkReferences":{},"immutableReferences":{"68284":[{"start":443,"length":32},{"start":1663,"length":32}]}},"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","burn(uint256)":"42966c68","getApproved(uint256)":"081812fc","getStateFingerprint(uint256)":"f5112315","hub()":"365a86fc","isApprovedForAll(address,address)":"e985e9c5","lastLoanId()":"68be92b4","loanContract(uint256)":"a00d21fc","mint(address)":"6a627842","name()":"06fdde03","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","symbol()":"95d89b41","tokenURI(uint256)":"c87b56dd","transferFrom(address,address,uint256)":"23b872dd"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_hub\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"CallerMissingHubTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLoanContractCaller\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"LOANBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"loanContract\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"LOANMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getStateFingerprint\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hub\",\"outputs\":[{\"internalType\":\"contract PWNHub\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastLoanId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"loanContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Token doesn't hold any loan logic, just an address of a loan contract that minted the LOAN token. PWN LOAN token is shared between all loan contracts.\",\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"burn(uint256)\":{\"details\":\"Any address that is associated with given loan id can call this function. It is enabled to let deprecated loan contracts repay and claim existing loans.\",\"params\":{\"loanId\":\"Id of a LOAN token to be burned.\"}},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"getStateFingerprint(uint256)\":{\"details\":\"See {IERC5646-getStateFingerprint}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"mint(address)\":{\"details\":\"Only an address with associated `ACTIVE_LOAN` tag in PWN Hub can call this function.\",\"params\":{\"owner\":\"Address of a LOAN token receiver.\"},\"returns\":{\"loanId\":\"Id of a newly minted LOAN token.\"}},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenURI(uint256)\":{\"params\":{\"tokenId\":\"Id of a LOAN token.\"},\"returns\":{\"_0\":\"Metadata uri for given token id (loan id).\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"stateVariables\":{\"lastLoanId\":{\"details\":\"Last used LOAN id. First LOAN id is 1. This value is incremental.\"},\"loanContract\":{\"details\":\"Mapping of a LOAN id to a loan contract that minted the LOAN token.\"}},\"title\":\"PWN LOAN token\",\"version\":1},\"userdoc\":{\"errors\":{\"CallerMissingHubTag(bytes32)\":[{\"notice\":\"Thrown when caller is missing a PWN Hub tag.\"}],\"InvalidLoanContractCaller()\":[{\"notice\":\"Thrown when `PWNLOAN.burn` caller is not a loan contract that minted the LOAN token.\"}]},\"events\":{\"LOANBurned(uint256)\":{\"notice\":\"Emitted when a LOAN token is burned.\"},\"LOANMinted(uint256,address,address)\":{\"notice\":\"Emitted when a new LOAN token is minted.\"}},\"kind\":\"user\",\"methods\":{\"burn(uint256)\":{\"notice\":\"Burn a LOAN token.\"},\"mint(address)\":{\"notice\":\"Mint a new LOAN token.\"},\"tokenURI(uint256)\":{\"notice\":\"Return a LOAN token metadata uri base on a loan contract that minted the token.\"}},\"notice\":\"A LOAN token representing a loan in PWN protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/loan/token/PWNLOAN.sol\":\"PWNLOAN\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005\",\"dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4\",\"dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]},\"src/hub/PWNHubTags.sol\":{\"keccak256\":\"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8\",\"dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ\"]},\"src/interfaces/IERC5646.sol\":{\"keccak256\":\"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180\",\"dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki\"]},\"src/interfaces/IPWNLoanMetadataProvider.sol\":{\"keccak256\":\"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6\",\"dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK\"]},\"src/loan/token/PWNLOAN.sol\":{\"keccak256\":\"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219\",\"dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_hub","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"tag","type":"bytes32"}],"type":"error","name":"CallerMissingHubTag"},{"inputs":[],"type":"error","name":"InvalidLoanContractCaller"},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"approved","type":"address","indexed":true},{"internalType":"uint256","name":"tokenId","type":"uint256","indexed":true}],"type":"event","name":"Approval","anonymous":false},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"operator","type":"address","indexed":true},{"internalType":"bool","name":"approved","type":"bool","indexed":false}],"type":"event","name":"ApprovalForAll","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true}],"type":"event","name":"LOANBurned","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"address","name":"loanContract","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true}],"type":"event","name":"LOANMinted","anonymous":false},{"inputs":[{"internalType":"address","name":"from","type":"address","indexed":true},{"internalType":"address","name":"to","type":"address","indexed":true},{"internalType":"uint256","name":"tokenId","type":"uint256","indexed":true}],"type":"event","name":"Transfer","anonymous":false},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"approve"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"burn"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getStateFingerprint","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"hub","outputs":[{"internalType":"contract PWNHub","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function","name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"lastLoanId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","name":"loanContract","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"mint","outputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"name","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"safeTransferFrom"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"safeTransferFrom"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setApprovalForAll"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transferFrom"}],"devdoc":{"kind":"dev","methods":{"approve(address,uint256)":{"details":"See {IERC721-approve}."},"balanceOf(address)":{"details":"See {IERC721-balanceOf}."},"burn(uint256)":{"details":"Any address that is associated with given loan id can call this function. It is enabled to let deprecated loan contracts repay and claim existing loans.","params":{"loanId":"Id of a LOAN token to be burned."}},"getApproved(uint256)":{"details":"See {IERC721-getApproved}."},"getStateFingerprint(uint256)":{"details":"See {IERC5646-getStateFingerprint}."},"isApprovedForAll(address,address)":{"details":"See {IERC721-isApprovedForAll}."},"mint(address)":{"details":"Only an address with associated `ACTIVE_LOAN` tag in PWN Hub can call this function.","params":{"owner":"Address of a LOAN token receiver."},"returns":{"loanId":"Id of a newly minted LOAN token."}},"name()":{"details":"See {IERC721Metadata-name}."},"ownerOf(uint256)":{"details":"See {IERC721-ownerOf}."},"safeTransferFrom(address,address,uint256)":{"details":"See {IERC721-safeTransferFrom}."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"See {IERC721-safeTransferFrom}."},"setApprovalForAll(address,bool)":{"details":"See {IERC721-setApprovalForAll}."},"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."},"symbol()":{"details":"See {IERC721Metadata-symbol}."},"tokenURI(uint256)":{"params":{"tokenId":"Id of a LOAN token."},"returns":{"_0":"Metadata uri for given token id (loan id)."}},"transferFrom(address,address,uint256)":{"details":"See {IERC721-transferFrom}."}},"version":1},"userdoc":{"kind":"user","methods":{"burn(uint256)":{"notice":"Burn a LOAN token."},"mint(address)":{"notice":"Mint a new LOAN token."},"tokenURI(uint256)":{"notice":"Return a LOAN token metadata uri base on a loan contract that minted the token."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/loan/token/PWNLOAN.sol":"PWNLOAN"},"evmVersion":"london","libraries":{}},"sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"},"src/hub/PWNHubTags.sol":{"keccak256":"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a","urls":["bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8","dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ"],"license":"GPL-3.0-only"},"src/interfaces/IERC5646.sol":{"keccak256":"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e","urls":["bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180","dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki"],"license":"GPL-3.0-only"},"src/interfaces/IPWNLoanMetadataProvider.sol":{"keccak256":"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8","urls":["bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6","dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK"],"license":"GPL-3.0-only"},"src/loan/token/PWNLOAN.sol":{"keccak256":"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb","urls":["bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219","dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo"],"license":"GPL-3.0-only"}},"version":1},"id":100} \ No newline at end of file +[ + { + "inputs": [{ "internalType": "address", "name": "hub", "type": "address" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "CallerMissingHubTag", + "type": "error" + }, + { "inputs": [], "name": "InvalidLoanContractCaller", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "loanId", + "type": "uint256" + } + ], + "name": "LOANBurned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "loanId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "loanContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "LOANMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "getApproved", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "getStateFingerprint", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isApprovedForAll", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastLoanId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "loanContract", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ownerOf", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "bool", "name": "approved", "type": "bool" } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "tokenURI", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/packages/subgraph/abis/MultiTokenCategoryRegistry.json b/packages/subgraph/abis/MultiTokenCategoryRegistry.json new file mode 100644 index 00000000..6b9e61d2 --- /dev/null +++ b/packages/subgraph/abis/MultiTokenCategoryRegistry.json @@ -0,0 +1,154 @@ +[ + { "inputs": [], "name": "ReservedCategoryValue", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint8", + "name": "category", + "type": "uint8" + } + ], + "name": "CategoryRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetAddress", + "type": "address" + } + ], + "name": "CategoryUnregistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "CATEGORY_NOT_REGISTERED", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "assetAddress", "type": "address" }, + { "internalType": "uint8", "name": "category", "type": "uint8" } + ], + "name": "registerCategoryValue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "assetAddress", "type": "address" } + ], + "name": "registeredCategoryValue", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "assetAddress", "type": "address" } + ], + "name": "unregisterCategoryValue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/packages/subgraph/abis/SimpleLoan.json b/packages/subgraph/abis/SimpleLoan.json index 647d7d6f..be22f0a4 100644 --- a/packages/subgraph/abis/SimpleLoan.json +++ b/packages/subgraph/abis/SimpleLoan.json @@ -1 +1,1100 @@ -{"abi":[{"type":"constructor","inputs":[{"name":"_hub","type":"address","internalType":"address"},{"name":"_loanToken","type":"address","internalType":"address"},{"name":"_config","type":"address","internalType":"address"},{"name":"_revokedNonce","type":"address","internalType":"address"},{"name":"_categoryRegistry","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"ACCRUING_INTEREST_APR_DECIMALS","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"ACCRUING_INTEREST_APR_DENOMINATOR","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"EXTENSION_PROPOSAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MAX_ACCRUING_INTEREST_APR","inputs":[],"outputs":[{"name":"","type":"uint40","internalType":"uint40"}],"stateMutability":"view"},{"type":"function","name":"MAX_EXTENSION_DURATION","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MINUTES_IN_YEAR","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MIN_EXTENSION_DURATION","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MIN_LOAN_DURATION","inputs":[],"outputs":[{"name":"","type":"uint32","internalType":"uint32"}],"stateMutability":"view"},{"type":"function","name":"VERSION","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"categoryRegistry","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IMultiTokenCategoryRegistry"}],"stateMutability":"view"},{"type":"function","name":"claimLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"config","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNConfig"}],"stateMutability":"view"},{"type":"function","name":"createLOAN","inputs":[{"name":"proposalSpec","type":"tuple","internalType":"struct PWNSimpleLoan.ProposalSpec","components":[{"name":"proposalContract","type":"address","internalType":"address"},{"name":"proposalData","type":"bytes","internalType":"bytes"},{"name":"proposalInclusionProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]},{"name":"lenderSpec","type":"tuple","internalType":"struct PWNSimpleLoan.LenderSpec","components":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]},{"name":"callerSpec","type":"tuple","internalType":"struct PWNSimpleLoan.CallerSpec","components":[{"name":"refinancingLoanId","type":"uint256","internalType":"uint256"},{"name":"revokeNonce","type":"bool","internalType":"bool"},{"name":"nonce","type":"uint256","internalType":"uint256"}]},{"name":"extra","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"extendLOAN","inputs":[{"name":"extension","type":"tuple","internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"extensionProposalsMade","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getExtensionHash","inputs":[{"name":"extension","type":"tuple","internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"status","type":"uint8","internalType":"uint8"},{"name":"startTimestamp","type":"uint40","internalType":"uint40"},{"name":"defaultTimestamp","type":"uint40","internalType":"uint40"},{"name":"borrower","type":"address","internalType":"address"},{"name":"originalLender","type":"address","internalType":"address"},{"name":"loanOwner","type":"address","internalType":"address"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"credit","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"collateral","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"originalSourceOfFunds","type":"address","internalType":"address"},{"name":"repaymentAmount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLenderSpecHash","inputs":[{"name":"lenderSpec","type":"tuple","internalType":"struct PWNSimpleLoan.LenderSpec","components":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"pure"},{"type":"function","name":"getStateFingerprint","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"hub","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNHub"}],"stateMutability":"view"},{"type":"function","name":"isValidAsset","inputs":[{"name":"asset","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"loanMetadataUri","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"loanRepaymentAmount","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"loanToken","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNLOAN"}],"stateMutability":"view"},{"type":"function","name":"makeExtensionProposal","inputs":[{"name":"extension","type":"tuple","internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onERC1155BatchReceived","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256[]","internalType":"uint256[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"pure"},{"type":"function","name":"onERC1155Received","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"type":"function","name":"onERC721Received","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"type":"function","name":"repayLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokedNonce","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract PWNRevokedNonce"}],"stateMutability":"view"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"type":"function","name":"tryClaimRepaidLOAN","inputs":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"creditAmount","type":"uint256","internalType":"uint256"},{"name":"loanOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"ExtensionProposalMade","inputs":[{"name":"extensionHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"proposer","type":"address","indexed":true,"internalType":"address"},{"name":"proposal","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoan.ExtensionProposal","components":[{"name":"loanId","type":"uint256","internalType":"uint256"},{"name":"compensationAddress","type":"address","internalType":"address"},{"name":"compensationAmount","type":"uint256","internalType":"uint256"},{"name":"duration","type":"uint40","internalType":"uint40"},{"name":"expiration","type":"uint40","internalType":"uint40"},{"name":"proposer","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]}],"anonymous":false},{"type":"event","name":"LOANClaimed","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"defaulted","type":"bool","indexed":true,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"LOANCreated","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"proposalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"proposalContract","type":"address","indexed":true,"internalType":"address"},{"name":"refinancingLoanId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"terms","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoan.Terms","components":[{"name":"lender","type":"address","internalType":"address"},{"name":"borrower","type":"address","internalType":"address"},{"name":"duration","type":"uint32","internalType":"uint32"},{"name":"collateral","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"credit","type":"tuple","internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"fixedInterestAmount","type":"uint256","internalType":"uint256"},{"name":"accruingInterestAPR","type":"uint24","internalType":"uint24"},{"name":"lenderSpecHash","type":"bytes32","internalType":"bytes32"},{"name":"borrowerSpecHash","type":"bytes32","internalType":"bytes32"}]},{"name":"lenderSpec","type":"tuple","indexed":false,"internalType":"struct PWNSimpleLoan.LenderSpec","components":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]},{"name":"extra","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"LOANExtended","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"originalDefaultTimestamp","type":"uint40","indexed":false,"internalType":"uint40"},{"name":"extendedDefaultTimestamp","type":"uint40","indexed":false,"internalType":"uint40"}],"anonymous":false},{"type":"event","name":"LOANPaidBack","inputs":[{"name":"loanId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"PoolSupply","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"poolAdapter","type":"address","indexed":true,"internalType":"address"},{"name":"pool","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"PoolWithdraw","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"poolAdapter","type":"address","indexed":true,"internalType":"address"},{"name":"pool","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultPull","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"origin","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultPush","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"beneficiary","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultPushFrom","inputs":[{"name":"asset","type":"tuple","indexed":false,"internalType":"struct MultiToken.Asset","components":[{"name":"category","type":"uint8","internalType":"enum MultiToken.Category"},{"name":"assetAddress","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"origin","type":"address","indexed":true,"internalType":"address"},{"name":"beneficiary","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"AddressMissingHubTag","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"tag","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"CallerNotLOANTokenHolder","inputs":[]},{"type":"error","name":"CallerNotVault","inputs":[]},{"type":"error","name":"Expired","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"expiration","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"IncompleteTransfer","inputs":[]},{"type":"error","name":"InterestAPROutOfBounds","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidDuration","inputs":[{"name":"current","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidExtensionCaller","inputs":[]},{"type":"error","name":"InvalidExtensionDuration","inputs":[{"name":"duration","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidExtensionSigner","inputs":[{"name":"allowed","type":"address","internalType":"address"},{"name":"current","type":"address","internalType":"address"}]},{"type":"error","name":"InvalidLenderSpecHash","inputs":[{"name":"current","type":"bytes32","internalType":"bytes32"},{"name":"expected","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidMultiTokenAsset","inputs":[{"name":"category","type":"uint8","internalType":"uint8"},{"name":"addr","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSignature","inputs":[{"name":"signer","type":"address","internalType":"address"},{"name":"digest","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidSignatureLength","inputs":[{"name":"length","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSourceOfFunds","inputs":[{"name":"sourceOfFunds","type":"address","internalType":"address"}]},{"type":"error","name":"LoanDefaulted","inputs":[{"name":"timestap","type":"uint40","internalType":"uint40"}]},{"type":"error","name":"LoanNotAutoclaimable","inputs":[]},{"type":"error","name":"LoanNotRepaid","inputs":[]},{"type":"error","name":"LoanNotRunning","inputs":[]},{"type":"error","name":"LoanRepaid","inputs":[]},{"type":"error","name":"LoanRunning","inputs":[]},{"type":"error","name":"NonExistingLoan","inputs":[]},{"type":"error","name":"NonceNotUsable","inputs":[{"name":"addr","type":"address","internalType":"address"},{"name":"nonceSpace","type":"uint256","internalType":"uint256"},{"name":"nonce","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"RefinanceBorrowerMismatch","inputs":[{"name":"currentBorrower","type":"address","internalType":"address"},{"name":"newBorrower","type":"address","internalType":"address"}]},{"type":"error","name":"RefinanceCollateralMismatch","inputs":[]},{"type":"error","name":"RefinanceCreditMismatch","inputs":[]},{"type":"error","name":"UnsupportedCategory","inputs":[{"name":"categoryValue","type":"uint8","internalType":"uint8"}]},{"type":"error","name":"UnsupportedTransferFunction","inputs":[]},{"type":"error","name":"VaultTransferSameSourceAndDestination","inputs":[{"name":"addr","type":"address","internalType":"address"}]}],"bytecode":{"object":"0x610180604052600361014090815262312e3360e81b610160527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f907f3af43dc47dd092dc79d11f941571a702d1419a15bb1e9b52d0e0e91e22f07352906200006a906101a062000121565b60408051601f1981840301815282825280516020918201209083019490945281019190915260608101919091524660808201523060a082015260c00160408051601f198184030181529190528051602090910120608052348015620000ce57600080fd5b506040516200507838038062005078833981016040819052620000f1916200016f565b60016000556001600160a01b0394851660a05292841660c05290831660e0528216610100521661012052620001df565b6000825160005b8181101562000144576020818601810151858301520162000128565b506000920191825250919050565b80516001600160a01b03811681146200016a57600080fd5b919050565b600080600080600060a086880312156200018857600080fd5b620001938662000152565b9450620001a36020870162000152565b9350620001b36040870162000152565b9250620001c36060870162000152565b9150620001d36080870162000152565b90509295509295909350565b60805160a05160c05160e0516101005161012051614dbd620002bb600039600081816103bd01526113c50152600081816104b50152818161098201528181610cc2015261161a0152600081816104530152818161074901528181611a74015281816126f6015281816127a9015281816128f801528181612aac01526133de01526000818161022d015281816105fe01528181610a990152818161108b015281816112dd015281816124940152818161286e0152612c5501526000818161033101526114ca01526000818161030a01526113ed0152614dbd6000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063706048df1161011a5780639788ad55116100ad578063c399e17d1161007c578063c399e17d146104fa578063c81980801461051a578063f23a6e611461052d578063f511231514610540578063ffa1ad741461055357600080fd5b80639788ad55146104b057806397b090ea146104d75780639e8f9540146104df578063bc197c81146104e757600080fd5b806379502c55116100e957806379502c551461044e5780637f24133f1461047557806389d99a051461047f57806394aedc2f1461049d57600080fd5b8063706048df146104025780637122192c1461041557806374baf6ef14610428578063764d77131461043b57600080fd5b80632c8ebec8116101925780633e6df512116101615780633e6df512146103665780634acacdda1461039157806358099d96146103b8578063640d16ed146103df57600080fd5b80632c8ebec8146102fb5780633644e51514610305578063365a86fc1461032c578063376af4d11461035357600080fd5b8063111d8a15116101ce578063111d8a1514610294578063150b7a02146102a95780631742123c146102d55780632c3eae8a146102e857600080fd5b806301ffc9a71461020057806306d37817146102285780630eb6f582146102675780630ee1ba171461027f575b600080fd5b61021361020e36600461405b565b610575565b60405190151581526020015b60405180910390f35b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161021f565b6102716208052081565b60405190815260200161021f565b61029261028d366004614085565b6105c7565b005b61029c610731565b60405161021f91906140ee565b6102bc6102b7366004614157565b6107c5565b6040516001600160e01b0319909116815260200161021f565b6102926102e33660046141e2565b610803565b6102716102f6366004614085565b610e91565b6102716276a70081565b6102717f000000000000000000000000000000000000000000000000000000000000000081565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610292610361366004614237565b610ed2565b610379610374366004614085565b610faf565b60405161021f9c9b9a999897969594939291906142b4565b6102717f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa71781565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102136103ed366004614085565b60026020526000908152604090205460ff1681565b610292610410366004614085565b6111c8565b610213610423366004614392565b6113bd565b610271610436366004614237565b6113e9565b610271610449366004614418565b6114b6565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102716201518081565b61048861025881565b60405163ffffffff909116815260200161021f565b6102926104ab3660046144a8565b611939565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610271611b2b565b610271606481565b6102bc6104f5366004614525565b611b47565b61050462f4240081565b60405164ffffffffff909116815260200161021f565b6102716105283660046145e3565b611b62565b6102bc61053b3660046145ff565b611b75565b61027161054e366004614085565b611bb3565b61029c60405180604001604052806003815260200162312e3360e81b81525081565b60006001600160e01b031982166301ffc9a760e01b14806105a657506001600160e01b03198216630a85bd0160e11b145b806105c157506001600160e01b03198216630271189760e51b145b92915050565b6105cf611c48565b6000818152600160205260409081902090516331a9108f60e11b81526004810183905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015610645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106699190614685565b6001600160a01b03161461069057604051632a0a3d8160e11b815260040160405180910390fd5b805460ff166000036106b5576040516335cee39560e01b815260040160405180910390fd5b805460ff166003036106d2576106cd82336000611ca1565b610723565b805460ff1660021480156106f95750600181015442600160c81b90910464ffffffffff1611155b1561070a576106cd82336001611ca1565b6040516311d01f2b60e31b815260040160405180910390fd5b5061072e6001600055565b50565b604051630233557560e41b81523060048201526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632335575090602401600060405180830381865afa158015610798573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107c091908101906146a2565b905090565b60006001600160a01b03861630146107f0576040516382a1dea160e01b815260040160405180910390fd5b50630a85bd0160e11b5b95945050505050565b61080b611c48565b823560009081526001602052604081208054909160ff9091169003610843576040516335cee39560e01b815260040160405180910390fd5b805460ff1660030361086857604051631062e18f60e01b815260040160405180910390fd5b6000610873856113e9565b60008181526002602052604090205490915060ff16610921576108dc61089f60c0870160a08801614743565b8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d8d92505050565b610921576108f060c0860160a08701614743565b6040516301d2d55760e31b81526001600160a01b039091166004820152602481018290526044015b60405180910390fd5b61093160a0860160808701614775565b64ffffffffff164210610978574261094f60a0870160808801614775565b60405163aa2fd92560e01b8152600481019290925264ffffffffff166024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f291a62c6109b760c0880160a08901614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08901356024820152908801356044820152606401602060405180830381865afa158015610a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a33919061479e565b610a8057610a4760c0860160a08701614743565b604051632108c30560e11b81526001600160a01b03909116600482015260c0860135602482015260e08601356044820152606401610918565b6040516331a9108f60e11b8152853560048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0c9190614685565b90506001600160a01b0381163303610b985760028301546001600160a01b0316610b3c60c0880160a08901614743565b6001600160a01b031614610b935760028301546001600160a01b0316610b6860c0880160a08901614743565b604051627c5e8760e31b81526001600160a01b03928316600482015291166024820152604401610918565b610bfe565b60028301546001600160a01b03163303610be5576001600160a01b038116610bc660c0880160a08901614743565b6001600160a01b031614610b935780610b6860c0880160a08901614743565b604051639d29f3a960e01b815260040160405180910390fd5b62015180610c126080880160608901614775565b64ffffffffff161015610c5b57610c2f6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff9091166004820152620151806024820152604401610918565b6276a700610c6f6080880160608901614775565b64ffffffffff161115610cb857610c8c6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff90911660048201526276a7006024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f79924a9610cf760c0890160a08a01614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08a01356024820152908901356044820152606401600060405180830381600087803b158015610d4c57600080fd5b505af1158015610d60573d6000803e3d6000fd5b505050506001830154600160c81b900464ffffffffff16610d876080880160608901614775565b610d9190826147d1565b60018501805464ffffffffff60c81b1916600160c81b64ffffffffff938416810291909117918290556040805185851681529190920490921660208301528835917f16e70f82a9a68fdbf6cc67068dcfadcaf1e0c61409aa3a24122767789ccc20d5910160405180910390a26000610e0f6040890160208a01614743565b6001600160a01b031614158015610e2a575060008760400135115b15610e7e576000610e5760408901803590610e489060208c01614743565b6001600160a01b031690611f33565b9050610e6281611f6b565b6002850154610e7c9082906001600160a01b031685611fd6565b505b50505050610e8c6001600055565b505050565b6000818152600160205260408120805460ff168203610eb35750600092915050565b610ebc8161204e565b8160050154610ecb91906147f6565b9392505050565b610ee260c0820160a08301614743565b6001600160a01b0316336001600160a01b031614610f3457610f0a60c0820160a08301614743565b604051627c5e8760e31b81526001600160a01b039091166004820152336024820152604401610918565b6000610f3f826113e9565b6000818152600260205260409020805460ff191660011790559050610f6a60c0830160a08401614743565b6001600160a01b0316817f3404b1a797c8c84bf93d13290f9f6e7464634602778a1ffa1fc7d8708668022e84604051610fa39190614809565b60405180910390a35050565b600080600080600080600080610fc3614029565b610fcb614029565b60008b81526001602052604081208190610fe48e612101565b9c508060010160149054906101000a900464ffffffffff169b508060010160199054906101000a900464ffffffffff169a508060020160009054906101000a90046001600160a01b031699508060030160009054906101000a90046001600160a01b031698508060000160009054906101000a900460ff1660ff1660000361106d5760006110f6565b6040516331a9108f60e11b8152600481018f90526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f69190614685565b6003820154600483015460058401548454939b50600160a01b90920462ffffff16995097506111339161010090046001600160a01b031690611f33565b60408051608081019091526006830180549297509091829060ff16600381111561115f5761115f614254565b600381111561117057611170614254565b815281546001600160a01b03610100909104811660208301526001808401546040840152600290930154606090920191909152908301549195501692506111b68e610e91565b91505091939597999b5091939597999b565b6111d0611c48565b600081815260016020819052604090912080549181015490916112069160ff90911690600160c81b900464ffffffffff1661214d565b61120f826121c9565b600061121a83610e91565b82549091506112419061123b9061010090046001600160a01b031683611f33565b33612230565b60408051608081019091526006830180546112bb929190829060ff16600381111561126e5761126e614254565b600381111561127f5761127f614254565b815281546001600160a01b036101009091048116602083015260018301546040830152600292830154606090920191909152908501541661229d565b6040516331a9108f60e11b81526004810184905230906394aedc2f90859084907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa15801561132c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113509190614685565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526001600160a01b03166044820152606401600060405180830381600087803b15801561139f57600080fd5b505af19250505080156113b0575060015b50505061072e6001600055565b60006105c1827f00000000000000000000000000000000000000000000000000000000000000006122fd565b60007f00000000000000000000000000000000000000000000000000000000000000007f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa7178360405160200161143e9190614809565b60408051601f198184030181529082905261145c929160200161489f565b6040516020818303038152906040528051906020012060405160200161149992919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b60006114c0611c48565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d019577a6114fc6020890189614743565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401602060405180830381865afa158015611566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158a919061479e565b6115e65761159b6020870187614743565b604051630b92eb2560e11b81526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401610918565b6115f660408501602086016148c5565b1561167f5760408051630a69412f60e21b81523360048201529085013560248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906329a504bc90604401600060405180830381600087803b15801561166657600080fd5b505af115801561167a573d6000803e3d6000fd5b505050505b8335156116ca578335600090815260016020819052604090912080549181015490916116be9160ff90911690600160c81b900464ffffffffff1661214d565b6116c885356121c9565b505b6000806116da6020890189614743565b6001600160a01b03166301e832723388356116f860208d018d6148e2565b61170560408f018f614928565b8f806060019061171591906148e2565b6040518963ffffffff1660e01b815260040161173898979695949392919061499a565b610200604051808303816000875af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190614ab6565b805191935091506001600160a01b031633148015906117a7575061179f87611b62565b8160e0015114155b156117dc578060e001516117ba88611b62565b604051633188f56d60e11b815260048101929092526024820152604401610918565b61025863ffffffff16816040015163ffffffff16101561182557604080820151905163387a058b60e01b815263ffffffff90911660048201526102586024820152604401610918565b62f4240064ffffffffff168160c0015162ffffff16111561186f5760c0810151604051630fb8adc560e41b815262ffffff909116600482015262f424006024820152604401610918565b8535600003611897576118858160800151611f6b565b6118928160600151611f6b565b6118a2565b6118a2863582612319565b6118ac8188612470565b92506118bb6020890189614743565b6001600160a01b031682847f81757c17b6937fd2ab5739a2842fe6165ef6bee2d0b24179f95fbf761634a68a8960000135858c8b8b604051611901959493929190614b96565b60405180910390a485356000036119215761191c81886126a7565b61192d565b61192d86358289612847565b50506107fa6001600055565b3330146119595760405163edd7338f60e01b815260040160405180910390fd5b6000838152600160205260409020805460ff1660031461198b57604051625bdcbf60e11b815260040160405180910390fd5b60038101546001600160a01b038381169116146119bb5760405163499174ef60e01b815260040160405180910390fd5b600181015481546001600160a01b03918216916000916119e2916101009091041686611f33565b90506119ed86612c3f565b60405160009087907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b73908390a384600003611a2a57505050505050565b836001600160a01b0316826001600160a01b031603611a5257611a4d818561229d565b611b23565b60405163b209123160e01b81526001600160a01b0383811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063b209123190602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190614685565b90506001600160a01b038116611b1557604051632f9526c360e11b81526001600160a01b0384166004820152602401610918565b611b2182828588612d35565b505b505050505050565b611b39620805206064614c5a565b611b44906064614c5a565b81565b60006040516382a1dea160e01b815260040160405180910390fd5b6000816040516020016114999190614c79565b60006001600160a01b0387163014611ba0576040516382a1dea160e01b815260040160405180910390fd5b5063f23a6e6160e01b9695505050505050565b6000818152600160205260408120805460ff168203611bd55750600092915050565b611bde83612101565b6001820154600483015460038401546040805160ff9095166020860152600160c81b90930464ffffffffff16928401929092526060830152600160a01b900462ffffff16608082015260a00160405160208183030381529060405280519060200120915050919050565b600260005403611c9a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610918565b6002600055565b60008381526001602052604081209082611cdc57611cd7611cc186610e91565b835461010090046001600160a01b031690611f33565b611d42565b6040805160808101909152600683018054829060ff166003811115611d0357611d03614254565b6003811115611d1457611d14614254565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546060909101525b9050611d4d85612c3f565b6040518315159086907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b7390600090a3611d86818561229d565b5050505050565b60006001600160a01b0384163b15611e8857600080856001600160a01b0316631626ba7e60e01b8686604051602401611dc7929190614c99565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611e059190614cb2565b600060405180830381855afa9150503d8060008114611e40576040519150601f19603f3d011682016040523d82523d6000602084013e611e45565b606091505b5091509150818015611e58575080516020145b8015611e7f57508051630b135d3f60e11b90611e7d9083016020908101908401614cce565b145b92505050610ecb565b60008060008451604103611eb05750505060208201516040830151606084015160001a611f07565b8451604003611ee957602085015160408601519093506001600160ff1b0381169250611ee160ff82901c601b6147f6565b915050611f07565b845160405163058676ad60e31b815260040161091891815260200190565b611f1386828585612e36565b6001600160a01b0316876001600160a01b03161493505050509392505050565b611f3b614029565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b611f74816113bd565b61072e5780516003811115611f8b57611f8b614254565b60208201516040808401516060850151915163032163e160e11b815260ff90941660048501526001600160a01b03909216602484015260448301919091526064820152608401610918565b6000611fe28483612e5e565b9050611fef8484846130a8565b611ffd8482848660016130b5565b816001600160a01b0316836001600160a01b03167f0272ef83f5953daad3d7708e6b4442e126f1e049e62a01c1fc53683f3277199c866040516120409190614ce7565b60405180910390a350505050565b6003810154600090600160a01b900462ffffff16810361207057506004015490565b6001820154600090603c9061209390600160a01b900464ffffffffff1642614cf5565b61209d9190614d1e565b600584015460038501549192506000916120e791906120c9908590600160a01b900462ffffff16614c5a565b6120d7620805206064614c5a565b6120e2906064614c5a565b61314f565b90508084600401546120f991906147f6565b949350505050565b6000818152600160205260408120805460ff1660021480156121365750600181015442600160c81b90910464ffffffffff1611155b61214457805460ff16610ecb565b60049392505050565b8160ff16600003612171576040516335cee39560e01b815260040160405180910390fd5b8160ff16600214612195576040516331fe4d5d60e01b815260040160405180910390fd5b428164ffffffffff16116121c557604051631e3cd61560e01b815264ffffffffff82166004820152602401610918565b5050565b6000818152600160205260409020805460ff191660031781556121eb8161204e565b600482015560038101805462ffffff60a01b1916905560405182907ff1e5b832ef53e7d611651983b38ff941f4d2049e9c8962c623c2664bca312bc090600090a25050565b600061223c8330612e5e565b9050612249838330613239565b6122578382308560016130b5565b816001600160a01b03167f019fcaae912e42069954835069f1c8184411022f86cf749694625f2a2313b6ab846040516122909190614ce7565b60405180910390a2505050565b60006122a98383612e5e565b90506122b68330846130a8565b6122c48382843060016130b5565b816001600160a01b03167fc2b8da69776ffa72ca2d7c4a31390d57bd4871cef8066bbe7f1e5bf220a310f1846040516122909190614ce7565b60006123098383613246565b8015610ecb5750610ecb836132f4565b6000828152600160209081526040909120608083015190910151815461010090046001600160a01b03908116911614158061235a5750608082015160600151155b1561237857604051635f860c6160e11b815260040160405180910390fd5b606082015151600381111561238f5761238f614254565b600682015460ff1660038111156123a8576123a8614254565b1415806123d35750606082015160200151600682015461010090046001600160a01b03908116911614155b806123ea5750606082015160400151600782015414155b8061240057506060808301510151600882015414155b1561241e5760405163175bb1b760e21b815260040160405180910390fd5b602082015160028201546001600160a01b03908116911614610e8c576002810154602083015160405163d4b919f760e01b81526001600160a01b03928316600482015291166024820152604401610918565b81516040516335313c2160e11b81526001600160a01b0391821660048201526000917f00000000000000000000000000000000000000000000000000000000000000001690636a627842906024016020604051808303816000875af11580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190614cce565b6000818152600160209081526040909120805460808701518301516001600160a01b0316610100026001600160a81b031990911617600217815591925061254a90840184614743565b60018201805464ffffffffff42908116600160a01b026001600160c81b03199092166001600160a01b03949094169390931717905560408501516125969163ffffffff909116906147d1565b6001808301805464ffffffffff93909316600160c81b0264ffffffffff60c81b199093169290921790915560208501516002830180546001600160a01b039283166001600160a01b031990911617905585516003808501805460c08a015162ffffff16600160a01b026001600160b81b0319909116939094169290921792909217905560a08601516004840155608086015160609081015160058501558601518051600685018054929490939192849260ff199091169190849081111561265f5761265f614254565b0217905550602082015181546001600160a01b0390911661010002610100600160a81b0319909116178155604082015160018201556060909101516002909101555092915050565b6126b982606001518360200151612230565b81516001600160a01b03166126d16020830183614743565b6001600160a01b0316146126ee576126ee826080015183836133d2565b6000806127847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127769190614d40565b8560800151606001516134e3565b60808601519193509150821561282e578281606001818152505061282e8186600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128299190614685565b611fd6565b6060810182905284516020860151611d86918391611fd6565b60008381526001602052604080822090516331a9108f60e11b8152600481018690529091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156128bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e19190614685565b905060006128ee86610e91565b90506000806129867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612954573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129789190614d40565b8860800151606001516134e3565b9150915060006129968483613524565b905060008483116129a85760006129b2565b6129b28584614cf5565b905060008082116129cc576129c78487614cf5565b6129cf565b60005b90506000876001600160a01b03168b600001516001600160a01b0316141580612a2f575060038901546001600160a01b038981169116148015612a2f5750612a1a60208b018b614743565b60018a01546001600160a01b03908116911614155b60808c01518c51919250906001600160a01b0316612a5060208d018d614743565b6001600160a01b031614612a91578382612a6b576000612a6d565b855b612a7790896147f6565b612a8191906147f6565b6060820152612a91818d8d6133d2565b8615612b085786816060018181525050612b08818d600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b8115612b2257606081018590528b51612b22908290612230565b8315612b4657606081018490528b5160208d0151612b41918391611fd6565b612b63565b8215612b63576060810183905260208c0151612b63908290612230565b306394aedc2f8e8585612b77576000612b79565b885b612b8391906147f6565b6040516001600160e01b031960e085901b168152600481019290925260248201526001600160a01b038c166044820152606401600060405180830381600087803b158015612bd057600080fd5b505af1925050508015612be1575060015b612c305781612c3057606081018590528b516001600160a01b0316612c0960208d018d614743565b6001600160a01b031614612c2257612c22818d8d6133d2565b612c30818d60000151612230565b50505050505050505050505050565b604051630852cd8d60e31b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b158015612ca157600080fd5b505af1158015612cb5573d6000803e3d6000fd5b505050600091825250600160208190526040822080546001600160a81b0319908116825591810180546001600160f01b03191690556002810180546001600160a01b03191690556003810180546001600160b81b031916905560048101839055600581018390556006810180549092169091556007810182905560080155565b6000612d418530612e5e565b9050612d4e853086613239565b6020850151606086015160405163107c8ed760e01b81526001600160a01b0386811660048301528581166024830152928316604482015260648101919091529085169063107c8ed790608401600060405180830381600087803b158015612db457600080fd5b505af1158015612dc8573d6000803e3d6000fd5b50505050612dda8582308660006130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167fb58f4e60b4600784c073e07e7bb67825fe64b4592b5c7ce254599a9b8dcc4d8288604051612e279190614ce7565b60405180910390a45050505050565b6000806000612e478787878761353a565b91509150612e54816135fe565b5095945050505050565b60008083516003811115612e7457612e74614254565b03612ef15760208301516040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024015b602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190614cce565b90506105c1565b600183516003811115612f0657612f06614254565b03612fae57816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b602060405180830381865afa158015612f68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8c9190614685565b6001600160a01b031614612fa1576000612fa4565b60015b60ff1690506105c1565b600283516003811115612fc357612fc3614254565b036130065760208301516040808501519051627eeac760e11b81526001600160a01b038581166004830152602482019290925291169062fdd58e90604401612ea9565b60038351600381111561301b5761301b614254565b0361306057816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b60405162461bcd60e51b815260206004820181905260248201527f4d756c7469546f6b656e3a20556e737570706f727465642063617465676f72796044820152606401610918565b610e8c8383836001613748565b816001600160a01b0316836001600160a01b0316036130f25760405163bb77337360e01b81526001600160a01b0384166004820152602401610918565b6000816131115761310286613a01565b61310c9086614cf5565b613124565b61311a86613a01565b61312490866147f6565b90506131308685612e5e565b8114611b23576040516345ffc53d60e11b815260040160405180910390fd5b60008080600019858709858702925082811083820303915050806000036131895783828161317f5761317f614d08565b0492505050610ecb565b8084116131d05760405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606401610918565b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b610e8c8383836000613748565b6020820151604051638481ab0760e01b81526001600160a01b039182166004820152600091829190841690638481ab0790602401602060405180830381865afa158015613297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bb9190614d64565b905060ff808216146132eb57835160ff82169060038111156132df576132df614254565b60ff16149150506105c1565b6120f984613a5c565b6000808251600381111561330a5761330a614254565b036133265760408201511561332157506000919050565b6133ca565b60018251600381111561333b5761333b614254565b036133525760608201511561332157506000919050565b60028251600381111561336757613367614254565b146133ca5760038251600381111561338157613381614254565b036133985760608201511561332157506000919050565b815160038111156133ab576133ab614254565b604051635928f9a360e11b815260ff9091166004820152602401610918565b506001919050565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b20912316134106020850185614743565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015613454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134789190614685565b90506001600160a01b0381166134ba576134956020830183614743565b604051632f9526c360e11b81526001600160a01b039091166004820152602401610918565b6060840151156134dd576134dd84826134d66020860186614743565b8651613bf2565b50505050565b6000808361ffff166000036134fd5750600090508161351d565b61350e838561ffff1661271061314f565b915061351a8284614cf5565b90505b9250929050565b60008183106135335781610ecb565b5090919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561357157506000905060036135f5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135c5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ee576000600192509250506135f5565b9150600090505b94509492505050565b600081600481111561361257613612614254565b0361361a5750565b600181600481111561362e5761362e614254565b0361367b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610918565b600281600481111561368f5761368f614254565b036136dc5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610918565b60038160048111156136f0576136f0614254565b0361072e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610918565b60008451600381111561375d5761375d614254565b036137c557306001600160a01b0384160361379d5761379882856060015186602001516001600160a01b0316613cd99092919063ffffffff16565b6134dd565b6137988383866060015187602001516001600160a01b0316613d3c909392919063ffffffff16565b6001845160038111156137da576137da614254565b036138b5578061385f57602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd906064015b600060405180830381600087803b15801561384257600080fd5b505af1158015613856573d6000803e3d6000fd5b505050506134dd565b60208401516040808601519051635c46a7ef60e11b81526001600160a01b03868116600483015285811660248301526044820192909252608060648201526000608482015291169063b88d4fde9060a401613828565b6002845160038111156138ca576138ca614254565b0361394f5783602001516001600160a01b031663f242432a8484876040015188606001516000146138ff578860600151613902565b60015b6040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260a06084820152600060a482015260c401613828565b60038451600381111561396457613964614254565b0361306057306001600160a01b038416036139b9576020840151604080860151905163a9059cbb60e01b81526001600160a01b038581166004830152602482019290925291169063a9059cbb90604401613828565b602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd90606401613828565b60008082516003811115613a1757613a17614254565b03613a2457506060015190565b600282516003811115613a3957613a39614254565b148015613a4a575060008260600151115b156133ca57506060015190565b919050565b60008082516003811115613a7257613a72614254565b03613b4757613a8d82602001516001600160a01b0316613d74565b15613b33576020820151613ab1906001600160a01b03166336372b0760e01b613d9c565b15613abe57506001919050565b6020820151613add906001600160a01b03166380ac58cd60e01b613d9c565b158015613b0657506020820151613b04906001600160a01b0316636cdb3d1360e11b613d9c565b155b80156105c157506020820151613b2c906001600160a01b0316639a20483d60e01b613d9c565b1592915050565b50602001516001600160a01b03163b151590565b600182516003811115613b5c57613b5c614254565b03613b805760208201516105c1906001600160a01b03166380ac58cd60e01b613e25565b600282516003811115613b9557613b95614254565b03613bb95760208201516105c1906001600160a01b0316636cdb3d1360e11b613e25565b600382516003811115613bce57613bce614254565b036133985760208201516105c1906001600160a01b0316639a20483d60e01b613e25565b6000613bfe8583612e5e565b60208601516060870151604051630b620b8160e01b81526001600160a01b038781166004830152868116602483015292831660448201526064810191909152919250851690630b620b8190608401600060405180830381600087803b158015613c6657600080fd5b505af1158015613c7a573d6000803e3d6000fd5b50505050613c8c8582848660016130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167f4c6641e50ab591b51c5b75ab0d3721eb0357eac106223e5d21b1ceb5c2abd30388604051612e279190614ce7565b6040516001600160a01b038316602482015260448101829052610e8c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613e41565b6040516001600160a01b03808516602483015283166044820152606481018290526134dd9085906323b872dd60e01b90608401613d05565b6000613d87826301ffc9a760e01b613d9c565b80156105c15750613b2c826001600160e01b03195b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015613e0e575060208210155b8015613e1a5750600081115b979650505050505050565b6000613e3083613d74565b8015610ecb5750610ecb8383613d9c565b6000613e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f169092919063ffffffff16565b9050805160001480613eb7575080806020019051810190613eb7919061479e565b610e8c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610918565b60606120f9848460008585600080866001600160a01b03168587604051613f3d9190614cb2565b60006040518083038185875af1925050503d8060008114613f7a576040519150601f19603f3d011682016040523d82523d6000602084013e613f7f565b606091505b5091509150613e1a8783838760608315613ffa578251600003613ff3576001600160a01b0385163b613ff35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610918565b50816120f9565b6120f9838381511561400f5781518083602001fd5b8060405162461bcd60e51b815260040161091891906140ee565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b60006020828403121561406d57600080fd5b81356001600160e01b031981168114610ecb57600080fd5b60006020828403121561409757600080fd5b5035919050565b60005b838110156140b95781810151838201526020016140a1565b50506000910152565b600081518084526140da81602086016020860161409e565b601f01601f19169290920160200192915050565b602081526000610ecb60208301846140c2565b6001600160a01b038116811461072e57600080fd5b60008083601f84011261412857600080fd5b5081356001600160401b0381111561413f57600080fd5b60208301915083602082850101111561351d57600080fd5b60008060008060006080868803121561416f57600080fd5b853561417a81614101565b9450602086013561418a81614101565b93506040860135925060608601356001600160401b038111156141ac57600080fd5b6141b888828901614116565b969995985093965092949392505050565b600061010082840312156141dc57600080fd5b50919050565b600080600061012084860312156141f857600080fd5b61420285856141c9565b92506101008401356001600160401b0381111561421e57600080fd5b61422a86828701614116565b9497909650939450505050565b6000610100828403121561424a57600080fd5b610ecb83836141c9565b634e487b7160e01b600052602160045260246000fd5b80516004811061428a57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b03169083015260408082015190830152606090810151910152565b60ff8d16815264ffffffffff8c811660208301528b1660408201526001600160a01b038a811660608301528981166080830152881660a082015262ffffff871660c082015260e08101869052610240810161431361010083018761426a565b61432161018083018661426a565b6001600160a01b039390931661020082015261022001529a9950505050505050505050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561437f5761437f614346565b60405290565b6004811061072e57600080fd5b6000608082840312156143a457600080fd5b604051608081018181106001600160401b03821117156143c6576143c6614346565b60405282356143d481614385565b815260208301356143e481614101565b6020820152604083810135908201526060928301359281019290925250919050565b6000602082840312156141dc57600080fd5b600080600080600085870360c081121561443157600080fd5b86356001600160401b038082111561444857600080fd5b908801906080828b03121561445c57600080fd5b81975061446c8a60208b01614406565b96506060603f198401121561448057600080fd5b60408901955060a089013592508083111561449a57600080fd5b50506141b888828901614116565b6000806000606084860312156144bd57600080fd5b833592506020840135915060408401356144d681614101565b809150509250925092565b60008083601f8401126144f357600080fd5b5081356001600160401b0381111561450a57600080fd5b6020830191508360208260051b850101111561351d57600080fd5b60008060008060008060008060a0898b03121561454157600080fd5b883561454c81614101565b9750602089013561455c81614101565b965060408901356001600160401b038082111561457857600080fd5b6145848c838d016144e1565b909850965060608b013591508082111561459d57600080fd5b6145a98c838d016144e1565b909650945060808b01359150808211156145c257600080fd5b506145cf8b828c01614116565b999c989b5096995094979396929594505050565b6000602082840312156145f557600080fd5b610ecb8383614406565b60008060008060008060a0878903121561461857600080fd5b863561462381614101565b9550602087013561463381614101565b9450604087013593506060870135925060808701356001600160401b0381111561465c57600080fd5b61466889828a01614116565b979a9699509497509295939492505050565b8051613a5781614101565b60006020828403121561469757600080fd5b8151610ecb81614101565b6000602082840312156146b457600080fd5b81516001600160401b03808211156146cb57600080fd5b818401915084601f8301126146df57600080fd5b8151818111156146f1576146f1614346565b604051601f8201601f19908116603f0116810190838211818310171561471957614719614346565b8160405282815287602084870101111561473257600080fd5b613e1a83602083016020880161409e565b60006020828403121561475557600080fd5b8135610ecb81614101565b803564ffffffffff81168114613a5757600080fd5b60006020828403121561478757600080fd5b610ecb82614760565b801515811461072e57600080fd5b6000602082840312156147b057600080fd5b8151610ecb81614790565b634e487b7160e01b600052601160045260246000fd5b64ffffffffff8181168382160190808211156147ef576147ef6147bb565b5092915050565b808201808211156105c1576105c16147bb565b813581526101008101602083013561482081614101565b6001600160a01b031660208301526040838101359083015261484460608401614760565b64ffffffffff80821660608501528061485f60808701614760565b166080850152505060a083013561487581614101565b6001600160a01b03811660a08401525060c083013560c083015260e083013560e083015292915050565b828152600082516148b781602085016020870161409e565b919091016020019392505050565b6000602082840312156148d757600080fd5b8135610ecb81614790565b6000808335601e198436030181126148f957600080fd5b8301803591506001600160401b0382111561491357600080fd5b60200191503681900382131561351d57600080fd5b6000808335601e1984360301811261493f57600080fd5b8301803591506001600160401b0382111561495957600080fd5b6020019150600581901b360382131561351d57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038916815287602082015260a0604082015260006149c260a08301888a614971565b82810360608401528581526001600160fb1b038611156149e157600080fd5b8560051b808860208401370182810360209081016080850152614a079082018587614971565b9b9a5050505050505050505050565b805163ffffffff81168114613a5757600080fd5b600060808284031215614a3c57600080fd5b604051608081018181106001600160401b0382111715614a5e57614a5e614346565b80604052508091508251614a7181614385565b81526020830151614a8181614101565b8060208301525060408301516040820152606083015160608201525092915050565b805162ffffff81168114613a5757600080fd5b600080828403610200811215614acb57600080fd5b835192506101e080601f1983011215614ae357600080fd5b614aeb61435c565b9150614af96020860161467a565b8252614b076040860161467a565b6020830152614b1860608601614a16565b6040830152614b2a8660808701614a2a565b6060830152610100614b3e87828801614a2a565b608084015261018086015160a0840152614b5b6101a08701614aa3565b60c08401526101c086015160e0840152940151938101939093525092909150565b8035614b8781614101565b6001600160a01b031690915250565b85815284516001600160a01b03166020820152600061024060208701516001600160a01b038116604085015250604087015163ffffffff81166060850152506060870151614be7608085018261426a565b506080870151610100614bfc8186018361426a565b60a089015161018086015260c089015162ffffff166101a086015260e08901516101c08601528801516101e085015250614c3a610200840187614b7c565b80610220840152614c4e8184018587614971565b98975050505050505050565b6000816000190483118215151615614c7457614c746147bb565b500290565b602081018235614c8881614101565b6001600160a01b0316909152919050565b8281526040602082015260006120f960408301846140c2565b60008251614cc481846020870161409e565b9190910192915050565b600060208284031215614ce057600080fd5b5051919050565b608081016105c1828461426a565b818103818111156105c1576105c16147bb565b634e487b7160e01b600052601260045260246000fd5b600082614d3b57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215614d5257600080fd5b815161ffff81168114610ecb57600080fd5b600060208284031215614d7657600080fd5b815160ff81168114610ecb57600080fdfea2646970667358221220825b2223fc99b9fa96f255726855d28b700266f4ef852c01cd8fe06f1662a89d64736f6c63430008100033","sourceMap":"2794:7:93:-:0;1359:46454;2794:7;;1359:46454;2794:7;;;-1:-1:-1;;;2794:7:93;;2626:95;;2731:26;;2777:25;;;;:::i;:::-;;;;-1:-1:-1;;2777:25:93;;;;;;;;;2767:36;;2777:25;2767:36;;;;2606:249;;;692:25:137;;;;733:18;;726:34;;;;776:18;;;769:34;;;;2813:13:93;819:18:137;;;812:34;2844:4:93;862:19:137;;;855:61;664:19;;2606:249:93;;;-1:-1:-1;;2606:249:93;;;;;;;;;2596:260;;2606:249;2596:260;;;;2552:304;;12670:402;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1716:1:46;1821:7;:22;-1:-1:-1;;;;;12839:18:93;;;;;12867:31;;;;;12908:27;;;;;12945:45;;;;13000:65;;;1359:46454;;14:414:137;145:3;183:6;177:13;208:1;218:129;232:6;229:1;226:13;218:129;;;330:4;314:14;;;310:25;;304:32;291:11;;;284:53;247:12;218:129;;;-1:-1:-1;402:1:137;366:16;;391:13;;;-1:-1:-1;366:16:137;14:414;-1:-1:-1;14:414:137:o;927:177::-;1006:13;;-1:-1:-1;;;;;1048:31:137;;1038:42;;1028:70;;1094:1;1091;1084:12;1028:70;927:177;;;:::o;1109:550::-;1215:6;1223;1231;1239;1247;1300:3;1288:9;1279:7;1275:23;1271:33;1268:53;;;1317:1;1314;1307:12;1268:53;1340:40;1370:9;1340:40;:::i;:::-;1330:50;;1399:49;1444:2;1433:9;1429:18;1399:49;:::i;:::-;1389:59;;1467:49;1512:2;1501:9;1497:18;1467:49;:::i;:::-;1457:59;;1535:49;1580:2;1569:9;1565:18;1535:49;:::i;:::-;1525:59;;1603:50;1648:3;1637:9;1633:19;1603:50;:::i;:::-;1593:60;;1109:550;;;;;;;;:::o;:::-;1359:46454:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063706048df1161011a5780639788ad55116100ad578063c399e17d1161007c578063c399e17d146104fa578063c81980801461051a578063f23a6e611461052d578063f511231514610540578063ffa1ad741461055357600080fd5b80639788ad55146104b057806397b090ea146104d75780639e8f9540146104df578063bc197c81146104e757600080fd5b806379502c55116100e957806379502c551461044e5780637f24133f1461047557806389d99a051461047f57806394aedc2f1461049d57600080fd5b8063706048df146104025780637122192c1461041557806374baf6ef14610428578063764d77131461043b57600080fd5b80632c8ebec8116101925780633e6df512116101615780633e6df512146103665780634acacdda1461039157806358099d96146103b8578063640d16ed146103df57600080fd5b80632c8ebec8146102fb5780633644e51514610305578063365a86fc1461032c578063376af4d11461035357600080fd5b8063111d8a15116101ce578063111d8a1514610294578063150b7a02146102a95780631742123c146102d55780632c3eae8a146102e857600080fd5b806301ffc9a71461020057806306d37817146102285780630eb6f582146102675780630ee1ba171461027f575b600080fd5b61021361020e36600461405b565b610575565b60405190151581526020015b60405180910390f35b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161021f565b6102716208052081565b60405190815260200161021f565b61029261028d366004614085565b6105c7565b005b61029c610731565b60405161021f91906140ee565b6102bc6102b7366004614157565b6107c5565b6040516001600160e01b0319909116815260200161021f565b6102926102e33660046141e2565b610803565b6102716102f6366004614085565b610e91565b6102716276a70081565b6102717f000000000000000000000000000000000000000000000000000000000000000081565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610292610361366004614237565b610ed2565b610379610374366004614085565b610faf565b60405161021f9c9b9a999897969594939291906142b4565b6102717f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa71781565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102136103ed366004614085565b60026020526000908152604090205460ff1681565b610292610410366004614085565b6111c8565b610213610423366004614392565b6113bd565b610271610436366004614237565b6113e9565b610271610449366004614418565b6114b6565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b6102716201518081565b61048861025881565b60405163ffffffff909116815260200161021f565b6102926104ab3660046144a8565b611939565b61024f7f000000000000000000000000000000000000000000000000000000000000000081565b610271611b2b565b610271606481565b6102bc6104f5366004614525565b611b47565b61050462f4240081565b60405164ffffffffff909116815260200161021f565b6102716105283660046145e3565b611b62565b6102bc61053b3660046145ff565b611b75565b61027161054e366004614085565b611bb3565b61029c60405180604001604052806003815260200162312e3360e81b81525081565b60006001600160e01b031982166301ffc9a760e01b14806105a657506001600160e01b03198216630a85bd0160e11b145b806105c157506001600160e01b03198216630271189760e51b145b92915050565b6105cf611c48565b6000818152600160205260409081902090516331a9108f60e11b81526004810183905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015610645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106699190614685565b6001600160a01b03161461069057604051632a0a3d8160e11b815260040160405180910390fd5b805460ff166000036106b5576040516335cee39560e01b815260040160405180910390fd5b805460ff166003036106d2576106cd82336000611ca1565b610723565b805460ff1660021480156106f95750600181015442600160c81b90910464ffffffffff1611155b1561070a576106cd82336001611ca1565b6040516311d01f2b60e31b815260040160405180910390fd5b5061072e6001600055565b50565b604051630233557560e41b81523060048201526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632335575090602401600060405180830381865afa158015610798573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107c091908101906146a2565b905090565b60006001600160a01b03861630146107f0576040516382a1dea160e01b815260040160405180910390fd5b50630a85bd0160e11b5b95945050505050565b61080b611c48565b823560009081526001602052604081208054909160ff9091169003610843576040516335cee39560e01b815260040160405180910390fd5b805460ff1660030361086857604051631062e18f60e01b815260040160405180910390fd5b6000610873856113e9565b60008181526002602052604090205490915060ff16610921576108dc61089f60c0870160a08801614743565b8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d8d92505050565b610921576108f060c0860160a08701614743565b6040516301d2d55760e31b81526001600160a01b039091166004820152602481018290526044015b60405180910390fd5b61093160a0860160808701614775565b64ffffffffff164210610978574261094f60a0870160808801614775565b60405163aa2fd92560e01b8152600481019290925264ffffffffff166024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f291a62c6109b760c0880160a08901614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08901356024820152908801356044820152606401602060405180830381865afa158015610a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a33919061479e565b610a8057610a4760c0860160a08701614743565b604051632108c30560e11b81526001600160a01b03909116600482015260c0860135602482015260e08601356044820152606401610918565b6040516331a9108f60e11b8152853560048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0c9190614685565b90506001600160a01b0381163303610b985760028301546001600160a01b0316610b3c60c0880160a08901614743565b6001600160a01b031614610b935760028301546001600160a01b0316610b6860c0880160a08901614743565b604051627c5e8760e31b81526001600160a01b03928316600482015291166024820152604401610918565b610bfe565b60028301546001600160a01b03163303610be5576001600160a01b038116610bc660c0880160a08901614743565b6001600160a01b031614610b935780610b6860c0880160a08901614743565b604051639d29f3a960e01b815260040160405180910390fd5b62015180610c126080880160608901614775565b64ffffffffff161015610c5b57610c2f6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff9091166004820152620151806024820152604401610918565b6276a700610c6f6080880160608901614775565b64ffffffffff161115610cb857610c8c6080870160608801614775565b604051631a16ab3160e11b815264ffffffffff90911660048201526276a7006024820152604401610918565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f79924a9610cf760c0890160a08a01614743565b60405160e083811b6001600160e01b03191682526001600160a01b0392909216600482015260c08a01356024820152908901356044820152606401600060405180830381600087803b158015610d4c57600080fd5b505af1158015610d60573d6000803e3d6000fd5b505050506001830154600160c81b900464ffffffffff16610d876080880160608901614775565b610d9190826147d1565b60018501805464ffffffffff60c81b1916600160c81b64ffffffffff938416810291909117918290556040805185851681529190920490921660208301528835917f16e70f82a9a68fdbf6cc67068dcfadcaf1e0c61409aa3a24122767789ccc20d5910160405180910390a26000610e0f6040890160208a01614743565b6001600160a01b031614158015610e2a575060008760400135115b15610e7e576000610e5760408901803590610e489060208c01614743565b6001600160a01b031690611f33565b9050610e6281611f6b565b6002850154610e7c9082906001600160a01b031685611fd6565b505b50505050610e8c6001600055565b505050565b6000818152600160205260408120805460ff168203610eb35750600092915050565b610ebc8161204e565b8160050154610ecb91906147f6565b9392505050565b610ee260c0820160a08301614743565b6001600160a01b0316336001600160a01b031614610f3457610f0a60c0820160a08301614743565b604051627c5e8760e31b81526001600160a01b039091166004820152336024820152604401610918565b6000610f3f826113e9565b6000818152600260205260409020805460ff191660011790559050610f6a60c0830160a08401614743565b6001600160a01b0316817f3404b1a797c8c84bf93d13290f9f6e7464634602778a1ffa1fc7d8708668022e84604051610fa39190614809565b60405180910390a35050565b600080600080600080600080610fc3614029565b610fcb614029565b60008b81526001602052604081208190610fe48e612101565b9c508060010160149054906101000a900464ffffffffff169b508060010160199054906101000a900464ffffffffff169a508060020160009054906101000a90046001600160a01b031699508060030160009054906101000a90046001600160a01b031698508060000160009054906101000a900460ff1660ff1660000361106d5760006110f6565b6040516331a9108f60e11b8152600481018f90526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f69190614685565b6003820154600483015460058401548454939b50600160a01b90920462ffffff16995097506111339161010090046001600160a01b031690611f33565b60408051608081019091526006830180549297509091829060ff16600381111561115f5761115f614254565b600381111561117057611170614254565b815281546001600160a01b03610100909104811660208301526001808401546040840152600290930154606090920191909152908301549195501692506111b68e610e91565b91505091939597999b5091939597999b565b6111d0611c48565b600081815260016020819052604090912080549181015490916112069160ff90911690600160c81b900464ffffffffff1661214d565b61120f826121c9565b600061121a83610e91565b82549091506112419061123b9061010090046001600160a01b031683611f33565b33612230565b60408051608081019091526006830180546112bb929190829060ff16600381111561126e5761126e614254565b600381111561127f5761127f614254565b815281546001600160a01b036101009091048116602083015260018301546040830152600292830154606090920191909152908501541661229d565b6040516331a9108f60e11b81526004810184905230906394aedc2f90859084907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa15801561132c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113509190614685565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526001600160a01b03166044820152606401600060405180830381600087803b15801561139f57600080fd5b505af19250505080156113b0575060015b50505061072e6001600055565b60006105c1827f00000000000000000000000000000000000000000000000000000000000000006122fd565b60007f00000000000000000000000000000000000000000000000000000000000000007f9ff198f1043fd251b64c2f21c2278160819a77a1da50cf8284dc53af040fa7178360405160200161143e9190614809565b60408051601f198184030181529082905261145c929160200161489f565b6040516020818303038152906040528051906020012060405160200161149992919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b60006114c0611c48565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d019577a6114fc6020890189614743565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401602060405180830381865afa158015611566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158a919061479e565b6115e65761159b6020870187614743565b604051630b92eb2560e11b81526001600160a01b0390911660048201527fc0ba7a416221f318a8087fd62f9ff407488b7f5501e79caf9b0666c2df326b9c6024820152604401610918565b6115f660408501602086016148c5565b1561167f5760408051630a69412f60e21b81523360048201529085013560248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906329a504bc90604401600060405180830381600087803b15801561166657600080fd5b505af115801561167a573d6000803e3d6000fd5b505050505b8335156116ca578335600090815260016020819052604090912080549181015490916116be9160ff90911690600160c81b900464ffffffffff1661214d565b6116c885356121c9565b505b6000806116da6020890189614743565b6001600160a01b03166301e832723388356116f860208d018d6148e2565b61170560408f018f614928565b8f806060019061171591906148e2565b6040518963ffffffff1660e01b815260040161173898979695949392919061499a565b610200604051808303816000875af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190614ab6565b805191935091506001600160a01b031633148015906117a7575061179f87611b62565b8160e0015114155b156117dc578060e001516117ba88611b62565b604051633188f56d60e11b815260048101929092526024820152604401610918565b61025863ffffffff16816040015163ffffffff16101561182557604080820151905163387a058b60e01b815263ffffffff90911660048201526102586024820152604401610918565b62f4240064ffffffffff168160c0015162ffffff16111561186f5760c0810151604051630fb8adc560e41b815262ffffff909116600482015262f424006024820152604401610918565b8535600003611897576118858160800151611f6b565b6118928160600151611f6b565b6118a2565b6118a2863582612319565b6118ac8188612470565b92506118bb6020890189614743565b6001600160a01b031682847f81757c17b6937fd2ab5739a2842fe6165ef6bee2d0b24179f95fbf761634a68a8960000135858c8b8b604051611901959493929190614b96565b60405180910390a485356000036119215761191c81886126a7565b61192d565b61192d86358289612847565b50506107fa6001600055565b3330146119595760405163edd7338f60e01b815260040160405180910390fd5b6000838152600160205260409020805460ff1660031461198b57604051625bdcbf60e11b815260040160405180910390fd5b60038101546001600160a01b038381169116146119bb5760405163499174ef60e01b815260040160405180910390fd5b600181015481546001600160a01b03918216916000916119e2916101009091041686611f33565b90506119ed86612c3f565b60405160009087907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b73908390a384600003611a2a57505050505050565b836001600160a01b0316826001600160a01b031603611a5257611a4d818561229d565b611b23565b60405163b209123160e01b81526001600160a01b0383811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063b209123190602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190614685565b90506001600160a01b038116611b1557604051632f9526c360e11b81526001600160a01b0384166004820152602401610918565b611b2182828588612d35565b505b505050505050565b611b39620805206064614c5a565b611b44906064614c5a565b81565b60006040516382a1dea160e01b815260040160405180910390fd5b6000816040516020016114999190614c79565b60006001600160a01b0387163014611ba0576040516382a1dea160e01b815260040160405180910390fd5b5063f23a6e6160e01b9695505050505050565b6000818152600160205260408120805460ff168203611bd55750600092915050565b611bde83612101565b6001820154600483015460038401546040805160ff9095166020860152600160c81b90930464ffffffffff16928401929092526060830152600160a01b900462ffffff16608082015260a00160405160208183030381529060405280519060200120915050919050565b600260005403611c9a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610918565b6002600055565b60008381526001602052604081209082611cdc57611cd7611cc186610e91565b835461010090046001600160a01b031690611f33565b611d42565b6040805160808101909152600683018054829060ff166003811115611d0357611d03614254565b6003811115611d1457611d14614254565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546060909101525b9050611d4d85612c3f565b6040518315159086907f01c41914692eda9e423c83b28344603636e57a2803060f6778fea9ba50e71b7390600090a3611d86818561229d565b5050505050565b60006001600160a01b0384163b15611e8857600080856001600160a01b0316631626ba7e60e01b8686604051602401611dc7929190614c99565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611e059190614cb2565b600060405180830381855afa9150503d8060008114611e40576040519150601f19603f3d011682016040523d82523d6000602084013e611e45565b606091505b5091509150818015611e58575080516020145b8015611e7f57508051630b135d3f60e11b90611e7d9083016020908101908401614cce565b145b92505050610ecb565b60008060008451604103611eb05750505060208201516040830151606084015160001a611f07565b8451604003611ee957602085015160408601519093506001600160ff1b0381169250611ee160ff82901c601b6147f6565b915050611f07565b845160405163058676ad60e31b815260040161091891815260200190565b611f1386828585612e36565b6001600160a01b0316876001600160a01b03161493505050509392505050565b611f3b614029565b506040805160808101825260008082526001600160a01b0394909416602082015290810192909252606082015290565b611f74816113bd565b61072e5780516003811115611f8b57611f8b614254565b60208201516040808401516060850151915163032163e160e11b815260ff90941660048501526001600160a01b03909216602484015260448301919091526064820152608401610918565b6000611fe28483612e5e565b9050611fef8484846130a8565b611ffd8482848660016130b5565b816001600160a01b0316836001600160a01b03167f0272ef83f5953daad3d7708e6b4442e126f1e049e62a01c1fc53683f3277199c866040516120409190614ce7565b60405180910390a350505050565b6003810154600090600160a01b900462ffffff16810361207057506004015490565b6001820154600090603c9061209390600160a01b900464ffffffffff1642614cf5565b61209d9190614d1e565b600584015460038501549192506000916120e791906120c9908590600160a01b900462ffffff16614c5a565b6120d7620805206064614c5a565b6120e2906064614c5a565b61314f565b90508084600401546120f991906147f6565b949350505050565b6000818152600160205260408120805460ff1660021480156121365750600181015442600160c81b90910464ffffffffff1611155b61214457805460ff16610ecb565b60049392505050565b8160ff16600003612171576040516335cee39560e01b815260040160405180910390fd5b8160ff16600214612195576040516331fe4d5d60e01b815260040160405180910390fd5b428164ffffffffff16116121c557604051631e3cd61560e01b815264ffffffffff82166004820152602401610918565b5050565b6000818152600160205260409020805460ff191660031781556121eb8161204e565b600482015560038101805462ffffff60a01b1916905560405182907ff1e5b832ef53e7d611651983b38ff941f4d2049e9c8962c623c2664bca312bc090600090a25050565b600061223c8330612e5e565b9050612249838330613239565b6122578382308560016130b5565b816001600160a01b03167f019fcaae912e42069954835069f1c8184411022f86cf749694625f2a2313b6ab846040516122909190614ce7565b60405180910390a2505050565b60006122a98383612e5e565b90506122b68330846130a8565b6122c48382843060016130b5565b816001600160a01b03167fc2b8da69776ffa72ca2d7c4a31390d57bd4871cef8066bbe7f1e5bf220a310f1846040516122909190614ce7565b60006123098383613246565b8015610ecb5750610ecb836132f4565b6000828152600160209081526040909120608083015190910151815461010090046001600160a01b03908116911614158061235a5750608082015160600151155b1561237857604051635f860c6160e11b815260040160405180910390fd5b606082015151600381111561238f5761238f614254565b600682015460ff1660038111156123a8576123a8614254565b1415806123d35750606082015160200151600682015461010090046001600160a01b03908116911614155b806123ea5750606082015160400151600782015414155b8061240057506060808301510151600882015414155b1561241e5760405163175bb1b760e21b815260040160405180910390fd5b602082015160028201546001600160a01b03908116911614610e8c576002810154602083015160405163d4b919f760e01b81526001600160a01b03928316600482015291166024820152604401610918565b81516040516335313c2160e11b81526001600160a01b0391821660048201526000917f00000000000000000000000000000000000000000000000000000000000000001690636a627842906024016020604051808303816000875af11580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190614cce565b6000818152600160209081526040909120805460808701518301516001600160a01b0316610100026001600160a81b031990911617600217815591925061254a90840184614743565b60018201805464ffffffffff42908116600160a01b026001600160c81b03199092166001600160a01b03949094169390931717905560408501516125969163ffffffff909116906147d1565b6001808301805464ffffffffff93909316600160c81b0264ffffffffff60c81b199093169290921790915560208501516002830180546001600160a01b039283166001600160a01b031990911617905585516003808501805460c08a015162ffffff16600160a01b026001600160b81b0319909116939094169290921792909217905560a08601516004840155608086015160609081015160058501558601518051600685018054929490939192849260ff199091169190849081111561265f5761265f614254565b0217905550602082015181546001600160a01b0390911661010002610100600160a81b0319909116178155604082015160018201556060909101516002909101555092915050565b6126b982606001518360200151612230565b81516001600160a01b03166126d16020830183614743565b6001600160a01b0316146126ee576126ee826080015183836133d2565b6000806127847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127769190614d40565b8560800151606001516134e3565b60808601519193509150821561282e578281606001818152505061282e8186600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128299190614685565b611fd6565b6060810182905284516020860151611d86918391611fd6565b60008381526001602052604080822090516331a9108f60e11b8152600481018690529091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156128bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e19190614685565b905060006128ee86610e91565b90506000806129867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015612954573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129789190614d40565b8860800151606001516134e3565b9150915060006129968483613524565b905060008483116129a85760006129b2565b6129b28584614cf5565b905060008082116129cc576129c78487614cf5565b6129cf565b60005b90506000876001600160a01b03168b600001516001600160a01b0316141580612a2f575060038901546001600160a01b038981169116148015612a2f5750612a1a60208b018b614743565b60018a01546001600160a01b03908116911614155b60808c01518c51919250906001600160a01b0316612a5060208d018d614743565b6001600160a01b031614612a91578382612a6b576000612a6d565b855b612a7790896147f6565b612a8191906147f6565b6060820152612a91818d8d6133d2565b8615612b085786816060018181525050612b08818d600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612805573d6000803e3d6000fd5b8115612b2257606081018590528b51612b22908290612230565b8315612b4657606081018490528b5160208d0151612b41918391611fd6565b612b63565b8215612b63576060810183905260208c0151612b63908290612230565b306394aedc2f8e8585612b77576000612b79565b885b612b8391906147f6565b6040516001600160e01b031960e085901b168152600481019290925260248201526001600160a01b038c166044820152606401600060405180830381600087803b158015612bd057600080fd5b505af1925050508015612be1575060015b612c305781612c3057606081018590528b516001600160a01b0316612c0960208d018d614743565b6001600160a01b031614612c2257612c22818d8d6133d2565b612c30818d60000151612230565b50505050505050505050505050565b604051630852cd8d60e31b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b158015612ca157600080fd5b505af1158015612cb5573d6000803e3d6000fd5b505050600091825250600160208190526040822080546001600160a81b0319908116825591810180546001600160f01b03191690556002810180546001600160a01b03191690556003810180546001600160b81b031916905560048101839055600581018390556006810180549092169091556007810182905560080155565b6000612d418530612e5e565b9050612d4e853086613239565b6020850151606086015160405163107c8ed760e01b81526001600160a01b0386811660048301528581166024830152928316604482015260648101919091529085169063107c8ed790608401600060405180830381600087803b158015612db457600080fd5b505af1158015612dc8573d6000803e3d6000fd5b50505050612dda8582308660006130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167fb58f4e60b4600784c073e07e7bb67825fe64b4592b5c7ce254599a9b8dcc4d8288604051612e279190614ce7565b60405180910390a45050505050565b6000806000612e478787878761353a565b91509150612e54816135fe565b5095945050505050565b60008083516003811115612e7457612e74614254565b03612ef15760208301516040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024015b602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190614cce565b90506105c1565b600183516003811115612f0657612f06614254565b03612fae57816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b602060405180830381865afa158015612f68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8c9190614685565b6001600160a01b031614612fa1576000612fa4565b60015b60ff1690506105c1565b600283516003811115612fc357612fc3614254565b036130065760208301516040808501519051627eeac760e11b81526001600160a01b038581166004830152602482019290925291169062fdd58e90604401612ea9565b60038351600381111561301b5761301b614254565b0361306057816001600160a01b031683602001516001600160a01b0316636352211e85604001516040518263ffffffff1660e01b8152600401612f4b91815260200190565b60405162461bcd60e51b815260206004820181905260248201527f4d756c7469546f6b656e3a20556e737570706f727465642063617465676f72796044820152606401610918565b610e8c8383836001613748565b816001600160a01b0316836001600160a01b0316036130f25760405163bb77337360e01b81526001600160a01b0384166004820152602401610918565b6000816131115761310286613a01565b61310c9086614cf5565b613124565b61311a86613a01565b61312490866147f6565b90506131308685612e5e565b8114611b23576040516345ffc53d60e11b815260040160405180910390fd5b60008080600019858709858702925082811083820303915050806000036131895783828161317f5761317f614d08565b0492505050610ecb565b8084116131d05760405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606401610918565b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b610e8c8383836000613748565b6020820151604051638481ab0760e01b81526001600160a01b039182166004820152600091829190841690638481ab0790602401602060405180830381865afa158015613297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bb9190614d64565b905060ff808216146132eb57835160ff82169060038111156132df576132df614254565b60ff16149150506105c1565b6120f984613a5c565b6000808251600381111561330a5761330a614254565b036133265760408201511561332157506000919050565b6133ca565b60018251600381111561333b5761333b614254565b036133525760608201511561332157506000919050565b60028251600381111561336757613367614254565b146133ca5760038251600381111561338157613381614254565b036133985760608201511561332157506000919050565b815160038111156133ab576133ab614254565b604051635928f9a360e11b815260ff9091166004820152602401610918565b506001919050565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b20912316134106020850185614743565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015613454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134789190614685565b90506001600160a01b0381166134ba576134956020830183614743565b604051632f9526c360e11b81526001600160a01b039091166004820152602401610918565b6060840151156134dd576134dd84826134d66020860186614743565b8651613bf2565b50505050565b6000808361ffff166000036134fd5750600090508161351d565b61350e838561ffff1661271061314f565b915061351a8284614cf5565b90505b9250929050565b60008183106135335781610ecb565b5090919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561357157506000905060036135f5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135c5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ee576000600192509250506135f5565b9150600090505b94509492505050565b600081600481111561361257613612614254565b0361361a5750565b600181600481111561362e5761362e614254565b0361367b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610918565b600281600481111561368f5761368f614254565b036136dc5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610918565b60038160048111156136f0576136f0614254565b0361072e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610918565b60008451600381111561375d5761375d614254565b036137c557306001600160a01b0384160361379d5761379882856060015186602001516001600160a01b0316613cd99092919063ffffffff16565b6134dd565b6137988383866060015187602001516001600160a01b0316613d3c909392919063ffffffff16565b6001845160038111156137da576137da614254565b036138b5578061385f57602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd906064015b600060405180830381600087803b15801561384257600080fd5b505af1158015613856573d6000803e3d6000fd5b505050506134dd565b60208401516040808601519051635c46a7ef60e11b81526001600160a01b03868116600483015285811660248301526044820192909252608060648201526000608482015291169063b88d4fde9060a401613828565b6002845160038111156138ca576138ca614254565b0361394f5783602001516001600160a01b031663f242432a8484876040015188606001516000146138ff578860600151613902565b60015b6040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260a06084820152600060a482015260c401613828565b60038451600381111561396457613964614254565b0361306057306001600160a01b038416036139b9576020840151604080860151905163a9059cbb60e01b81526001600160a01b038581166004830152602482019290925291169063a9059cbb90604401613828565b602084015160408086015190516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201929092529116906323b872dd90606401613828565b60008082516003811115613a1757613a17614254565b03613a2457506060015190565b600282516003811115613a3957613a39614254565b148015613a4a575060008260600151115b156133ca57506060015190565b919050565b60008082516003811115613a7257613a72614254565b03613b4757613a8d82602001516001600160a01b0316613d74565b15613b33576020820151613ab1906001600160a01b03166336372b0760e01b613d9c565b15613abe57506001919050565b6020820151613add906001600160a01b03166380ac58cd60e01b613d9c565b158015613b0657506020820151613b04906001600160a01b0316636cdb3d1360e11b613d9c565b155b80156105c157506020820151613b2c906001600160a01b0316639a20483d60e01b613d9c565b1592915050565b50602001516001600160a01b03163b151590565b600182516003811115613b5c57613b5c614254565b03613b805760208201516105c1906001600160a01b03166380ac58cd60e01b613e25565b600282516003811115613b9557613b95614254565b03613bb95760208201516105c1906001600160a01b0316636cdb3d1360e11b613e25565b600382516003811115613bce57613bce614254565b036133985760208201516105c1906001600160a01b0316639a20483d60e01b613e25565b6000613bfe8583612e5e565b60208601516060870151604051630b620b8160e01b81526001600160a01b038781166004830152868116602483015292831660448201526064810191909152919250851690630b620b8190608401600060405180830381600087803b158015613c6657600080fd5b505af1158015613c7a573d6000803e3d6000fd5b50505050613c8c8582848660016130b5565b816001600160a01b0316836001600160a01b0316856001600160a01b03167f4c6641e50ab591b51c5b75ab0d3721eb0357eac106223e5d21b1ceb5c2abd30388604051612e279190614ce7565b6040516001600160a01b038316602482015260448101829052610e8c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613e41565b6040516001600160a01b03808516602483015283166044820152606481018290526134dd9085906323b872dd60e01b90608401613d05565b6000613d87826301ffc9a760e01b613d9c565b80156105c15750613b2c826001600160e01b03195b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015613e0e575060208210155b8015613e1a5750600081115b979650505050505050565b6000613e3083613d74565b8015610ecb5750610ecb8383613d9c565b6000613e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f169092919063ffffffff16565b9050805160001480613eb7575080806020019051810190613eb7919061479e565b610e8c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610918565b60606120f9848460008585600080866001600160a01b03168587604051613f3d9190614cb2565b60006040518083038185875af1925050503d8060008114613f7a576040519150601f19603f3d011682016040523d82523d6000602084013e613f7f565b606091505b5091509150613e1a8783838760608315613ffa578251600003613ff3576001600160a01b0385163b613ff35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610918565b50816120f9565b6120f9838381511561400f5781518083602001fd5b8060405162461bcd60e51b815260040161091891906140ee565b6040805160808101909152806000815260200160006001600160a01b0316815260200160008152602001600081525090565b60006020828403121561406d57600080fd5b81356001600160e01b031981168114610ecb57600080fd5b60006020828403121561409757600080fd5b5035919050565b60005b838110156140b95781810151838201526020016140a1565b50506000910152565b600081518084526140da81602086016020860161409e565b601f01601f19169290920160200192915050565b602081526000610ecb60208301846140c2565b6001600160a01b038116811461072e57600080fd5b60008083601f84011261412857600080fd5b5081356001600160401b0381111561413f57600080fd5b60208301915083602082850101111561351d57600080fd5b60008060008060006080868803121561416f57600080fd5b853561417a81614101565b9450602086013561418a81614101565b93506040860135925060608601356001600160401b038111156141ac57600080fd5b6141b888828901614116565b969995985093965092949392505050565b600061010082840312156141dc57600080fd5b50919050565b600080600061012084860312156141f857600080fd5b61420285856141c9565b92506101008401356001600160401b0381111561421e57600080fd5b61422a86828701614116565b9497909650939450505050565b6000610100828403121561424a57600080fd5b610ecb83836141c9565b634e487b7160e01b600052602160045260246000fd5b80516004811061428a57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b03169083015260408082015190830152606090810151910152565b60ff8d16815264ffffffffff8c811660208301528b1660408201526001600160a01b038a811660608301528981166080830152881660a082015262ffffff871660c082015260e08101869052610240810161431361010083018761426a565b61432161018083018661426a565b6001600160a01b039390931661020082015261022001529a9950505050505050505050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561437f5761437f614346565b60405290565b6004811061072e57600080fd5b6000608082840312156143a457600080fd5b604051608081018181106001600160401b03821117156143c6576143c6614346565b60405282356143d481614385565b815260208301356143e481614101565b6020820152604083810135908201526060928301359281019290925250919050565b6000602082840312156141dc57600080fd5b600080600080600085870360c081121561443157600080fd5b86356001600160401b038082111561444857600080fd5b908801906080828b03121561445c57600080fd5b81975061446c8a60208b01614406565b96506060603f198401121561448057600080fd5b60408901955060a089013592508083111561449a57600080fd5b50506141b888828901614116565b6000806000606084860312156144bd57600080fd5b833592506020840135915060408401356144d681614101565b809150509250925092565b60008083601f8401126144f357600080fd5b5081356001600160401b0381111561450a57600080fd5b6020830191508360208260051b850101111561351d57600080fd5b60008060008060008060008060a0898b03121561454157600080fd5b883561454c81614101565b9750602089013561455c81614101565b965060408901356001600160401b038082111561457857600080fd5b6145848c838d016144e1565b909850965060608b013591508082111561459d57600080fd5b6145a98c838d016144e1565b909650945060808b01359150808211156145c257600080fd5b506145cf8b828c01614116565b999c989b5096995094979396929594505050565b6000602082840312156145f557600080fd5b610ecb8383614406565b60008060008060008060a0878903121561461857600080fd5b863561462381614101565b9550602087013561463381614101565b9450604087013593506060870135925060808701356001600160401b0381111561465c57600080fd5b61466889828a01614116565b979a9699509497509295939492505050565b8051613a5781614101565b60006020828403121561469757600080fd5b8151610ecb81614101565b6000602082840312156146b457600080fd5b81516001600160401b03808211156146cb57600080fd5b818401915084601f8301126146df57600080fd5b8151818111156146f1576146f1614346565b604051601f8201601f19908116603f0116810190838211818310171561471957614719614346565b8160405282815287602084870101111561473257600080fd5b613e1a83602083016020880161409e565b60006020828403121561475557600080fd5b8135610ecb81614101565b803564ffffffffff81168114613a5757600080fd5b60006020828403121561478757600080fd5b610ecb82614760565b801515811461072e57600080fd5b6000602082840312156147b057600080fd5b8151610ecb81614790565b634e487b7160e01b600052601160045260246000fd5b64ffffffffff8181168382160190808211156147ef576147ef6147bb565b5092915050565b808201808211156105c1576105c16147bb565b813581526101008101602083013561482081614101565b6001600160a01b031660208301526040838101359083015261484460608401614760565b64ffffffffff80821660608501528061485f60808701614760565b166080850152505060a083013561487581614101565b6001600160a01b03811660a08401525060c083013560c083015260e083013560e083015292915050565b828152600082516148b781602085016020870161409e565b919091016020019392505050565b6000602082840312156148d757600080fd5b8135610ecb81614790565b6000808335601e198436030181126148f957600080fd5b8301803591506001600160401b0382111561491357600080fd5b60200191503681900382131561351d57600080fd5b6000808335601e1984360301811261493f57600080fd5b8301803591506001600160401b0382111561495957600080fd5b6020019150600581901b360382131561351d57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038916815287602082015260a0604082015260006149c260a08301888a614971565b82810360608401528581526001600160fb1b038611156149e157600080fd5b8560051b808860208401370182810360209081016080850152614a079082018587614971565b9b9a5050505050505050505050565b805163ffffffff81168114613a5757600080fd5b600060808284031215614a3c57600080fd5b604051608081018181106001600160401b0382111715614a5e57614a5e614346565b80604052508091508251614a7181614385565b81526020830151614a8181614101565b8060208301525060408301516040820152606083015160608201525092915050565b805162ffffff81168114613a5757600080fd5b600080828403610200811215614acb57600080fd5b835192506101e080601f1983011215614ae357600080fd5b614aeb61435c565b9150614af96020860161467a565b8252614b076040860161467a565b6020830152614b1860608601614a16565b6040830152614b2a8660808701614a2a565b6060830152610100614b3e87828801614a2a565b608084015261018086015160a0840152614b5b6101a08701614aa3565b60c08401526101c086015160e0840152940151938101939093525092909150565b8035614b8781614101565b6001600160a01b031690915250565b85815284516001600160a01b03166020820152600061024060208701516001600160a01b038116604085015250604087015163ffffffff81166060850152506060870151614be7608085018261426a565b506080870151610100614bfc8186018361426a565b60a089015161018086015260c089015162ffffff166101a086015260e08901516101c08601528801516101e085015250614c3a610200840187614b7c565b80610220840152614c4e8184018587614971565b98975050505050505050565b6000816000190483118215151615614c7457614c746147bb565b500290565b602081018235614c8881614101565b6001600160a01b0316909152919050565b8281526040602082015260006120f960408301846140c2565b60008251614cc481846020870161409e565b9190910192915050565b600060208284031215614ce057600080fd5b5051919050565b608081016105c1828461426a565b818103818111156105c1576105c16147bb565b634e487b7160e01b600052601260045260246000fd5b600082614d3b57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215614d5257600080fd5b815161ffff81168114610ecb57600080fd5b600060208284031215614d7657600080fd5b815160ff81168114610ecb57600080fdfea2646970667358221220825b2223fc99b9fa96f255726855d28b700266f4ef852c01cd8fe06f1662a89d64736f6c63430008100033","sourceMap":"1359:46454:93:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11525:298:102;;;;;;:::i;:::-;;:::i;:::-;;;470:14:137;;463:22;445:41;;433:2;418:18;11525:298:102;;;;;;;;2896:34:93;;;;;;;;-1:-1:-1;;;;;678:32:137;;;660:51;;648:2;633:18;2896:34:93;497:220:137;1955:49:93;;1997:7;1955:49;;;;;868:25:137;;;856:2;841:18;1955:49:93;722:177:137;32058:859:93;;;;;;:::i;:::-;;:::i;:::-;;46535:135;;;:::i;:::-;;;;;;;:::i;8944:341:102:-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3254:33:137;;;3236:52;;3224:2;3209:18;8944:341:102;3092:202:137;38008:3666:93;;;;;;:::i;:::-;;:::i;30557:323::-;;;;;;:::i;:::-;;:::i;2168:56::-;;2217:7;2168:56;;2552:304;;;;;2863:27;;;;;37170:513;;;;;;:::i;:::-;;:::i;43568:1139::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;2292:253::-;;2346:199;2292:253;;3026:61;;;;;8344:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;27796:956;;;;;;:::i;:::-;;:::i;45557:147::-;;;;;;:::i;:::-;;:::i;41845:347::-;;;;;;:::i;:::-;;:::i;14272:3571::-;;;;;;:::i;:::-;;:::i;2936:33::-;;;;;2230:55;;2279:6;2230:55;;1735:53;;1778:10;1735:53;;;;;10114:10:137;10102:23;;;10084:42;;10072:2;10057:18;1735:53:93;9940:192:137;33581:2191:93;;;;;;:::i;:::-;;:::i;2975:45::-;;;;;2047:114;;;:::i;1889:60::-;;1946:3;1889:60;;10676:295:102;;;;;;:::i;:::-;;:::i;1794:55:93:-;;1845:4;1794:55;;;;;12647:12:137;12635:25;;;12617:44;;12605:2;12590:18;1794:55:93;12473:194:137;13449:146:93;;;;;;:::i;:::-;;:::i;9782:366:102:-;;;;;;:::i;:::-;;:::i;46923:887:93:-;;;;;;:::i;:::-;;:::i;1488:38::-;;;;;;;;;;;;;;;-1:-1:-1;;;1488:38:93;;;;;11525:298:102;11612:4;-1:-1:-1;;;;;;11647:40:102;;-1:-1:-1;;;11647:40:102;;:104;;-1:-1:-1;;;;;;;11703:48:102;;-1:-1:-1;;;11703:48:102;11647:104;:169;;;-1:-1:-1;;;;;;;11767:49:102;;-1:-1:-1;;;11767:49:102;11647:169;11628:188;11525:298;-1:-1:-1;;11525:298:102:o;32058:859:93:-;2261:21:46;:19;:21::i;:::-;32125:17:93::1;32145:13:::0;;;:5:::1;:13;::::0;;;;;;32223:25;;-1:-1:-1;;;32223:25:93;;::::1;::::0;::::1;868::137::0;;;32252:10:93::1;::::0;-1:-1:-1;;;;;32223:9:93::1;:17;::::0;::::1;::::0;841:18:137;;32223:25:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;32223:39:93::1;;32219:90;;32283:26;;-1:-1:-1::0;;;32283:26:93::1;;;;;;;;;;;32219:90;32324:11:::0;;::::1;;;:16:::0;32320:590:::1;;32431:17;;-1:-1:-1::0;;;32431:17:93::1;;;;;;;;;;;32320:590;32467:11:::0;;::::1;;32482:1;32467:16:::0;32463:447:::1;;32536:77;32563:6;32582:10;32605:5;32536:16;:77::i;:::-;32463:447;;;32632:11:::0;;::::1;;32647:1;32632:16;:60:::0;::::1;;;-1:-1:-1::0;32652:21:93::1;::::0;::::1;::::0;32677:15:::1;-1:-1:-1::0;;;32652:21:93;;::::1;;;:40;;32632:60;32628:282;;;32749:76;32776:6;32795:10;32818:4;32749:16;:76::i;32628:282::-;32897:13;;-1:-1:-1::0;;;32897:13:93::1;;;;;;;;;;;32628:282;32115:802;2303:20:46::0;1716:1;2809:7;:22;2629:209;2303:20;32058:859:93;:::o;46535:135::-;46626:37;;-1:-1:-1;;;46626:37:93;;46657:4;46626:37;;;660:51:137;46594:13:93;;46626:6;-1:-1:-1;;;;;46626:22:93;;;;633:18:137;;46626:37:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46626:37:93;;;;;;;;;;;;:::i;:::-;46619:44;;46535:135;:::o;8944:341:102:-;9122:6;-1:-1:-1;;;;;9144:25:102;;9164:4;9144:25;9140:79;;9190:29;;-1:-1:-1;;;9190:29:102;;;;;;;;;;;9140:79;-1:-1:-1;;;;8944:341:102;;;;;;;;:::o;38008:3666:93:-;2261:21:46;:19;:21::i;:::-;38172:16:93;::::1;38146:17;38166:23:::0;;;:5:::1;:23;::::0;;;;38253:11;;38166:23;;38253:11:::1;::::0;;::::1;:16:::0;;38249:58:::1;;38290:17;;-1:-1:-1::0;;;38290:17:93::1;;;;;;;;;;;38249:58;38321:11:::0;;::::1;;38336:1;38321:16:::0;38317:82:::1;;38387:12;;-1:-1:-1::0;;;38387:12:93::1;;;;;;;;;;;38317:82;38446:21;38470:27;38487:9;38470:16;:27::i;:::-;38512:37;::::0;;;:22:::1;:37;::::0;;;;;38446:51;;-1:-1:-1;38512:37:93::1;;38507:262;;38568:85;38608:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;38628:13;38643:9;;38568:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;38568:39:93::1;::::0;-1:-1:-1;;;38568:85:93:i:1;:::-;38563:206;;38725:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;38678:91;::::0;-1:-1:-1;;;38678:91:93;;-1:-1:-1;;;;;15703:32:137;;;38678:91:93::1;::::0;::::1;15685:51:137::0;15752:18;;;15745:34;;;15658:18;;38678:91:93::1;;;;;;;;38563:206;38841:20;::::0;;;::::1;::::0;::::1;;:::i;:::-;38822:39;;:15;:39;38818:135;;38901:15;38930:20;::::0;;;::::1;::::0;::::1;;:::i;:::-;38882:71;::::0;-1:-1:-1;;;38882:71:93;;::::1;::::0;::::1;16322:25:137::0;;;;16395:12;16383:25;16363:18;;;16356:53;16295:18;;38882:71:93::1;16149:266:137::0;38818:135:93::1;-1:-1:-1::0;;;;;39002:12:93::1;:26;;39029:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;39002:85;::::0;39071:15:::1;39002:85:::0;;;-1:-1:-1;;;;;;39002:85:93;;;-1:-1:-1;;;;;16640:32:137;;;;39002:85:93::1;::::0;::::1;16622:51:137::0;39049:20:93::1;::::0;::::1;;16689:18:137::0;;;16682:34;39071:15:93;;::::1;;16732:18:137::0;;;16725:34;16595:18;;39002:85:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38997:289;;39163:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;39108:178;::::0;-1:-1:-1;;;39108:178:93;;-1:-1:-1;;;;;16640:32:137;;;39108:178:93::1;::::0;::::1;16622:51:137::0;39211:20:93::1;::::0;::::1;;16689:18:137::0;;;16682:34;39256:15:93::1;::::0;::::1;;16732:18:137::0;;;16725:34;16595:18;;39108:178:93::1;16420:345:137::0;38997:289:93::1;39352:35;::::0;-1:-1:-1;;;39352:35:93;;39370:16;::::1;39352:35;::::0;::::1;868:25:137::0;39332:17:93::1;::::0;39352:9:::1;-1:-1:-1::0;;;;;39352:17:93::1;::::0;::::1;::::0;841:18:137;;39352:35:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39332:55:::0;-1:-1:-1;;;;;;39401:23:93;::::1;:10;:23:::0;39397:795:::1;;39466:13;::::0;::::1;::::0;-1:-1:-1;;;;;39466:13:93::1;39444:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;39444:35:93::1;;39440:286;;39630:13;::::0;::::1;::::0;-1:-1:-1;;;;;39630:13:93::1;39674:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;39576:135;::::0;-1:-1:-1;;;39576:135:93;;-1:-1:-1;;;;;17373:15:137;;;39576:135:93::1;::::0;::::1;17355:34:137::0;17425:15;;17405:18;;;17398:43;17290:18;;39576:135:93::1;17143:304:137::0;39440:286:93::1;39397:795;;;39760:13;::::0;::::1;::::0;-1:-1:-1;;;;;39760:13:93::1;39746:10;:27:::0;39742:450:::1;;-1:-1:-1::0;;;;;39793:31:93;::::1;:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;39793:31:93::1;;39789:278;;39975:9:::0;40015:18:::1;::::0;;;::::1;::::0;::::1;;:::i;39742:450::-;40157:24;;-1:-1:-1::0;;;40157:24:93::1;;;;;;;;;;;39742:450;2279:6;40238:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;:43;;;40234:201;;;40355:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40302:133;::::0;-1:-1:-1;;;40302:133:93;;17655:12:137;17643:25;;;40302:133:93::1;::::0;::::1;17625:44:137::0;2279:6:93::1;17685:18:137::0;;;17678:34;17598:18;;40302:133:93::1;17452:266:137::0;40234:201:93::1;2217:7;40449:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;:43;;;40445:201;;;40566:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40513:133;::::0;-1:-1:-1;;;40513:133:93;;17655:12:137;17643:25;;;40513:133:93::1;::::0;::::1;17625:44:137::0;2217:7:93::1;17685:18:137::0;;;17678:34;17598:18;;40513:133:93::1;17452:266:137::0;40445:201:93::1;-1:-1:-1::0;;;;;40700:12:93::1;:24;;40725:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40700:83;::::0;40767:15:::1;40700:83:::0;;;-1:-1:-1;;;;;;40700:83:93;;;-1:-1:-1;;;;;16640:32:137;;;;40700:83:93::1;::::0;::::1;16622:51:137::0;40745:20:93::1;::::0;::::1;;16689:18:137::0;;;16682:34;40767:15:93;;::::1;;16732:18:137::0;;;16725:34;16595:18;;40700:83:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;40851:21:93::1;::::0;::::1;::::0;-1:-1:-1;;;40851:21:93;::::1;;;40933:18;::::0;;;::::1;::::0;::::1;;:::i;:::-;40906:45;::::0;:24;:45:::1;:::i;:::-;40882:21;::::0;::::1;:69:::0;;-1:-1:-1;;;;40882:69:93::1;-1:-1:-1::0;;;40882:69:93::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;40989:187:::1;::::0;;18253:15:137;;;18235:34;;41144:21:93;;;::::1;::::0;;::::1;18300:2:137::0;18285:18;;18278:43;41024:16:93;::::1;::::0;40989:187:::1;::::0;18177:18:137;40989:187:93::1;;;;;;;41286:1;41245:29;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;41245:43:93::1;;;:79;;;;;41323:1;41292:9;:28;;;:32;41245:79;41241:427;;;41340:36;41379:65;41415:28;::::0;::::1;::::0;::::1;::::0;41379:29:::1;::::0;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;41379:35:93::1;::::0;::::1;:65::i;:::-;41340:104;;41508:30;41525:12;41508:16;:30::i;:::-;41632:13;::::0;::::1;::::0;41608:49:::1;::::0;41618:12;;-1:-1:-1;;;;;41632:13:93::1;41647:9:::0;41608::::1;:49::i;:::-;41326:342;41241:427;38136:3538;;;;2303:20:46::0;1716:1;2809:7;:22;2629:209;2303:20;38008:3666:93;;;:::o;30557:323::-;30623:7;30662:13;;;:5;:13;;;;;30725:11;;;;:16;;30721:30;;-1:-1:-1;30750:1:93;;30557:323;-1:-1:-1;;30557:323:93:o;30721:30::-;30847:26;30868:4;30847:20;:26::i;:::-;30824:4;:20;;;:49;;;;:::i;:::-;30817:56;30557:323;-1:-1:-1;;;30557:323:93:o;37170:513::-;37319:18;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37305:32:93;:10;-1:-1:-1;;;;;37305:32:93;;37301:133;;37392:18;;;;;;;;:::i;:::-;37358:76;;-1:-1:-1;;;37358:76:93;;-1:-1:-1;;;;;17373:15:137;;;37358:76:93;;;17355:34:137;37421:10:93;17405:18:137;;;17398:43;17290:18;;37358:76:93;17143:304:137;37301:133:93;37488:21;37512:27;37529:9;37512:16;:27::i;:::-;37549:37;;;;:22;:37;;;;;:44;;-1:-1:-1;;37549:44:93;37589:4;37549:44;;;37488:51;-1:-1:-1;37646:18:93;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37609:67:93;37631:13;37609:67;37666:9;37609:67;;;;;;:::i;:::-;;;;;;;;37248:435;37170:513;:::o;43568:1139::-;43633:12;43655:21;43686:23;43719:16;43745:22;43777:17;43804:26;43840:27;43877:30;;:::i;:::-;43917:34;;:::i;:::-;43961:29;44060:13;;;:5;:13;;;;;43961:29;;44093:22;44066:6;44093:14;:22::i;:::-;44084:31;;44142:4;:19;;;;;;;;;;;;44125:36;;44190:4;:21;;;;;;;;;;;;44171:40;;44232:4;:13;;;;;;;;;;-1:-1:-1;;;;;44232:13:93;44221:24;;44272:4;:19;;;;;;;;;;-1:-1:-1;;;;;44272:19:93;44255:36;;44313:4;:11;;;;;;;;;;;;:16;;44328:1;44313:16;:57;;44368:1;44313:57;;;44332:25;;-1:-1:-1;;;44332:25:93;;;;;868::137;;;-1:-1:-1;;;;;44332:9:93;:17;;;;841:18:137;;44332:25:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44402:24;;;;44458;;;;44526:20;;;;44501:18;;44301:69;;-1:-1:-1;;;;44402:24:93;;;;;;-1:-1:-1;44458:24:93;-1:-1:-1;44501:46:93;;44402:24;44501:18;;-1:-1:-1;;;;;44501:18:93;;:24;:46::i;:::-;44557:28;;;;;;;;;44570:15;;;44557:28;;44492:55;;-1:-1:-1;44557:28:93;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;44557:28:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44619:26;;;;44557:28;;-1:-1:-1;44619:26:93;;-1:-1:-1;44673:27:93;44693:6;44673:19;:27::i;:::-;44655:45;;44030:677;43568:1139;;;;;;;;;;;;;:::o;27796:956::-;2261:21:46;:19;:21::i;:::-;27863:17:93::1;27883:13:::0;;;:5:::1;:13;::::0;;;;;;;27929:11;;27942:21;;::::1;::::0;27883:13;;27907:57:::1;::::0;27929:11:::1;::::0;;::::1;::::0;-1:-1:-1;;;27942:21:93;::::1;;;27907;:57::i;:::-;28014:25;28032:6;28014:17;:25::i;:::-;28101:23;28127:27;28147:6;28127:19;:27::i;:::-;28170:18:::0;;28101:53;;-1:-1:-1;28164:60:93::1;::::0;28170:41:::1;::::0;:18:::1;::::0;::::1;-1:-1:-1::0;;;;;28170:18:93::1;28101:53:::0;28170:24:::1;:41::i;:::-;28213:10;28164:5;:60::i;:::-;28283:37;::::0;;::::1;::::0;::::1;::::0;;;28289:15:::1;::::0;::::1;28283:37:::0;;::::1;::::0;;28289:15;28283:37;;::::1;;;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;;;-1:-1:-1;;;;;28283:37:93::1;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;28306:13;;::::1;::::0;::::1;28283:5;:37::i;:::-;28417:25;::::0;-1:-1:-1;;;28417:25:93;;::::1;::::0;::::1;868::137::0;;;28368:4:93::1;::::0;:23:::1;::::0;28392:6;;28400:15;;28417:9:::1;-1:-1:-1::0;;;;;28417:17:93::1;::::0;::::1;::::0;841:18:137;;28417:25:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28368:75;::::0;-1:-1:-1;;;;;;28368:75:93::1;::::0;;;;;;::::1;::::0;::::1;19703:25:137::0;;;;19744:18;;;19737:34;;;;-1:-1:-1;;;;;19807:32:137;19787:18;;;19780:60;19676:18;;28368:75:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;28364:382:::0;27853:899:::1;;2303:20:46::0;1716:1;2809:7;:22;2629:209;45557:147:93;45631:4;45654:43;45673:5;45680:16;45654:18;:43::i;41845:347::-;41930:7;42019:16;2346:199;42149:9;42138:21;;;;;;;;:::i;:::-;;;;-1:-1:-1;;42138:21:93;;;;;;;;;;42059:114;;;42138:21;42059:114;;:::i;:::-;;;;;;;;;;;;;42049:125;;;;;;41966:218;;;;;;;;-1:-1:-1;;;20473:27:137;;20525:1;20516:11;;20509:27;;;;20561:2;20552:12;;20545:28;20598:2;20589:12;;20215:392;41966:218:93;;;;;;;;;;;;;41956:229;;;;;;41949:236;;41845:347;;;:::o;14272:3571::-;14483:14;2261:21:46;:19;:21::i;:::-;-1:-1:-1;;;;;14558:3:93::1;:10;;14569:29;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;14558:67;::::0;-1:-1:-1;;;;;;14558:67:93::1;::::0;;;;;;-1:-1:-1;;;;;15703:32:137;;;14558:67:93::1;::::0;::::1;15685:51:137::0;422:30:82::1;15752:18:137::0;;;15745:34;15658:18;;14558:67:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14553:198;;14677:29;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;14648:92;::::0;-1:-1:-1;;;14648:92:93;;-1:-1:-1;;;;;15703:32:137;;;14648:92:93::1;::::0;::::1;15685:51:137::0;422:30:82::1;15752:18:137::0;;;15745:34;15658:18;;14648:92:93::1;15511:274:137::0;14553:198:93::1;14799:22;::::0;;;::::1;::::0;::::1;;:::i;:::-;14795:107;;;14874:16;14837:54:::0;;-1:-1:-1;;;14837:54:93;;14862:10:::1;14837:54;::::0;::::1;15685:51:137::0;14874:16:93;;::::1;;15752:18:137::0;;;15745:34;14837:12:93::1;-1:-1:-1::0;;;;;14837:24:93::1;::::0;::::1;::::0;15658:18:137;;14837:54:93::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;14795:107;14991:28:::0;::::1;:33:::0;14987:295:::1;;15066:28:::0;::::1;15040:17;15060:35:::0;;;:5:::1;:35;::::0;;;;;;;15131:11;;15144:21;;::::1;::::0;15060:35;;15109:57:::1;::::0;15131:11:::1;::::0;;::::1;::::0;-1:-1:-1;;;15144:21:93;::::1;;;15109;:57::i;:::-;15224:47;15242:28:::0;::::1;15224:17;:47::i;:::-;15026:256;14987:295;15339:20;::::0;15409:29:::1;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;-1:-1:-1::0;;;;;15387:80:93::1;;15496:10;15543:28:::0;::::1;15603:25;;::::0;::::1;:12:::0;:25:::1;:::i;:::-;15670:35;;::::0;::::1;:12:::0;:35:::1;:::i;:::-;15734:12;:22;;;;;;;;:::i;:::-;15387:384;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15854:16:::0;;15338:433;;-1:-1:-1;15854:16:93;-1:-1:-1;;;;;;15840:30:93::1;:10;:30;::::0;::::1;::::0;:91:::1;;;15902:29;15920:10;15902:17;:29::i;:::-;15874:9;:24;;;:57;;15840:91;15836:230;;;15987:9;:24;;;16023:29;16041:10;16023:17;:29::i;:::-;15954:101;::::0;-1:-1:-1;;;15954:101:93;;::::1;::::0;::::1;25835:25:137::0;;;;25876:18;;;25869:34;25808:18;;15954:101:93::1;25661:248:137::0;15836:230:93::1;1778:10;16119:38;;:9;:18;;;:38;;;16115:150;;;16207:18;::::0;;::::1;::::0;16180:74;;-1:-1:-1;;;16180:74:93;;26096:10:137;26133:15;;;16180:74:93::1;::::0;::::1;26115:34:137::0;1778:10:93::1;26165:18:137::0;;;26158:43;26059:18;;16180:74:93::1;25914:293:137::0;16115:150:93::1;1845:4;16326:57;;:9;:29;;;:57;;;16322:195;;;16440:29;::::0;::::1;::::0;16406:100:::1;::::0;-1:-1:-1;;;16406:100:93;;26414:8:137;26402:21;;;16406:100:93::1;::::0;::::1;26384:40:137::0;1845:4:93::1;26440:18:137::0;;;26433:53;26357:18;;16406:100:93::1;26212:280:137::0;16322:195:93::1;16531:28:::0;::::1;;:33:::0;16527:345:::1;;16637:34;16654:9;:16;;;16637;:34::i;:::-;16685:38;16702:9;:20;;;16685:16;:38::i;:::-;16527:345;;;16796:65;16821:28:::0;::::1;16851:9:::0;16796:24:::1;:65::i;:::-;16920:93;16957:9;16992:10;16920:11;:93::i;:::-;16911:102:::0;-1:-1:-1;17141:29:93::1;;::::0;::::1;:12:::0;:29:::1;:::i;:::-;-1:-1:-1::0;;;;;17029:305:93::1;17097:12;17063:6;17029:305;17203:10;:28;;;17252:9;17287:10;17318:5;;17029:305;;;;;;;;;;:::i;:::-;;;;;;;;17376:28:::0;::::1;;:33:::0;17372:465:::1;;17492:37;17507:9;17518:10;17492:14;:37::i;:::-;17372:465;;;17647:179;17705:28:::0;::::1;17762:9:::0;17801:10;17647:20:::1;:179::i;:::-;14499:3344;;2303:20:46::0;1716:1;2809:7;:22;2629:209;33581:2191:93;33689:10;33711:4;33689:27;33685:68;;33737:16;;-1:-1:-1;;;33737:16:93;;;;;;;;;;;33685:68;33764:17;33784:13;;;:5;:13;;;;;33856:11;;;;33871:1;33856:16;33852:56;;33893:15;;-1:-1:-1;;;33893:15:93;;;;;;;;;;;33852:56;34039:19;;;;-1:-1:-1;;;;;34039:32:93;;;:19;;:32;34035:79;;34092:22;;-1:-1:-1;;;34092:22:93;;;;;;;;;;;34035:79;34225:26;;;;34303:18;;-1:-1:-1;;;;;34225:26:93;;;;34196;;34303:38;;34225:26;34303:18;;;;34328:12;34303:24;:38::i;:::-;34261:80;;34427:19;34439:6;34427:11;:19::i;:::-;34462:49;;34503:5;;34484:6;;34462:49;;34503:5;;34462:49;34575:12;34591:1;34575:17;34571:42;;34606:7;;;33581:2191;;;:::o;34571:42::-;34786:9;-1:-1:-1;;;;;34764:31:93;:18;-1:-1:-1;;;;;34764:31:93;;34760:759;;34811:33;34817:15;34834:9;34811:5;:33::i;:::-;34760:759;;;34902:41;;-1:-1:-1;;;34902:41:93;;-1:-1:-1;;;;;678:32:137;;;34902:41:93;;;660:51:137;34875:24:93;;34902:6;:21;;;;;;633:18:137;;34902:41:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34875:68;-1:-1:-1;;;;;;35015:34:93;;35011:348;;35285:59;;-1:-1:-1;;;35285:59:93;;-1:-1:-1;;;;;678:32:137;;35285:59:93;;;660:51:137;633:18;;35285:59:93;497:220:137;35011:348:93;35434:74;35448:15;35465:11;35478:18;35498:9;35434:13;:74::i;:::-;34861:658;34760:759;33675:2097;;;33581:2191;;;:::o;2047:114::-;2107:48;1997:7;1946:3;2107:48;:::i;:::-;:54;;2158:3;2107:54;:::i;:::-;2047:114;:::o;10676:295:102:-;10910:6;10935:29;;-1:-1:-1;;;10935:29:102;;;;;;;;;;;13449:146:93;13529:7;13576:10;13565:22;;;;;;;;:::i;9782:366:102:-;9983:6;-1:-1:-1;;;;;10005:25:102;;10025:4;10005:25;10001:79;;10051:29;;-1:-1:-1;;;10051:29:102;;;;;;;;;;;10001:79;-1:-1:-1;;;;9782:366:102;;;;;;;;:::o;46923:887:93:-;47009:7;47048:14;;;:5;:14;;;;;47077:11;;;;:16;;47073:51;;-1:-1:-1;47122:1:93;;46923:887;-1:-1:-1;;46923:887:93:o;47073:51::-;47658:23;47673:7;47658:14;:23::i;:::-;47695:21;;;;47730:24;;;;47768;;;;47634:168;;;29204:4:137;29192:17;;;47634:168:93;;;29174:36:137;-1:-1:-1;;;47695:21:93;;;;;29226:18:137;;;29219:53;;;;29288:18;;;29281:34;-1:-1:-1;;;47768:24:93;;;;29331:18:137;;;29324:49;29146:19;;47634:168:93;;;;;;;;;;;;47624:179;;;;;;47617:186;;;46923:887;;;:::o;2336:287:46:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:46;;29586:2:137;2460:63:46;;;29568:21:137;29625:2;29605:18;;;29598:30;29664:33;29644:18;;;29637:61;29715:18;;2460:63:46;29384:355:137;2460:63:46;1759:1;2598:7;:18;2336:287::o;35997:599:93:-;36092:17;36112:13;;;:5;:13;;;;;;36220:9;:107;;36274:53;36299:27;36319:6;36299:19;:27::i;:::-;36274:18;;;;;-1:-1:-1;;;;;36274:18:93;;:24;:53::i;:::-;36220:107;;;;;;;;;;;;36244:15;;;36220:107;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;36220:107:93;;;;;;;;;;;;;;;;;;;;;;;;36188:139;;36413:19;36425:6;36413:11;:19::i;:::-;36448:53;;;;;;36470:6;;36448:53;;;;;36566:23;36572:5;36579:9;36566:5;:23::i;:::-;36082:514;;35997:599;;;:::o;1541:1696:92:-;1677:4;-1:-1:-1;;;;;1759:18:92;;;:22;1755:1476;;1798:12;1812:19;1835:6;-1:-1:-1;;;;;1835:17:92;1893:34;;;1929:4;1935:9;1870:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1870:75:92;;;;;;;;;;;;;;-1:-1:-1;;;;;1870:75:92;-1:-1:-1;;;;;;1870:75:92;;;;;;;;;;1835:124;;;;1870:75;1835:124;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1797:162;;;;1996:7;:46;;;;;2023:6;:13;2040:2;2023:19;1996:46;:142;;;;-1:-1:-1;2062:29:92;;-1:-1:-1;;;2103:34:92;2062:29;;;;;;;;;;;;:::i;:::-;:76;1996:142;1973:165;;;;;;1755:1476;2226:9;2249;2272:7;2348:9;:16;2368:2;2348:22;2344:817;;-1:-1:-1;;;2447:4:92;2432:20;;2426:27;2500:4;2485:20;;2479:27;2561:4;2546:20;;2540:27;2537:1;2532:36;2344:817;;;2686:9;:16;2706:2;2686:22;2682:479;;2814:4;2799:20;;2793:27;2868:4;2853:20;;2847:27;2793;;-1:-1:-1;;;;;;2914:80:92;;;-1:-1:-1;3022:25:92;3038:3;3023:18;;;3045:2;3022:25;:::i;:::-;3012:36;;2710:353;2682:479;;;3127:9;:16;3094:52;;-1:-1:-1;;;3094:52:92;;;;;;868:25:137;;856:2;841:18;;722:177;2682:479:92;3192:28;3206:4;3212:1;3215;3218;3192:13;:28::i;:::-;-1:-1:-1;;;;;3182:38:92;:6;-1:-1:-1;;;;;3182:38:92;;3175:45;;;;;1541:1696;;;;;:::o;2542:160:0:-;2618:12;;:::i;:::-;-1:-1:-1;2649:46:0;;;;;;;;-1:-1:-1;2649:46:0;;;-1:-1:-1;;;;;2649:46:0;;;;;;;;;;;;;;;;;;;;2542:160::o;45925:341:93:-;46010:19;46023:5;46010:12;:19::i;:::-;46005:255;;46109:14;;46103:21;;;;;;;;:::i;:::-;46148:18;;;;46188:8;;;;;46222:12;;;;46052:197;;-1:-1:-1;;;46052:197:93;;30776:4:137;30764:17;;;46052:197:93;;;30746:36:137;-1:-1:-1;;;;;30818:32:137;;;30798:18;;;30791:60;30867:18;;;30860:34;;;;30910:18;;;30903:34;30718:19;;46052:197:93;30519:424:137;4842:515:102;4948:23;4974:28;:5;4990:11;4974:15;:28::i;:::-;4948:54;-1:-1:-1;5013:48:102;:5;5041:6;5049:11;5013:27;:48::i;:::-;5071:222;5107:5;5143:15;5188:11;5234:6;5278:4;5071:14;:222::i;:::-;5338:11;-1:-1:-1;;;;;5309:41:102;5330:6;-1:-1:-1;;;;;5309:41:102;;5323:5;5309:41;;;;;;:::i;:::-;;;;;;;;4938:419;4842:515;;;:::o;31031:501:93:-;31125:24;;;;31102:7;;-1:-1:-1;;;31125:24:93;;;;:29;;31121:78;;-1:-1:-1;31175:24:93;;;;31031:501::o;31121:78::-;31255:19;;;;31210:23;;31278:9;;31237:37;;-1:-1:-1;;;31255:19:93;;;;31237:15;:37;:::i;:::-;31236:51;;;;:::i;:::-;31348:20;;;;31378:24;;;;31210:77;;-1:-1:-1;31297:23:93;;31323:143;;31348:20;31370:51;;31210:77;;-1:-1:-1;;;31378:24:93;;;;31370:51;:::i;:::-;2107:48;1997:7;1946:3;2107:48;:::i;:::-;:54;;2158:3;2107:54;:::i;:::-;31323:11;:143::i;:::-;31297:169;;31510:15;31483:4;:24;;;:42;;;;:::i;:::-;31476:49;31031:501;-1:-1:-1;;;;31031:501:93:o;44874:216::-;44936:5;44973:13;;;:5;:13;;;;;45004:11;;;;45019:1;45004:16;:60;;;;-1:-1:-1;45024:21:93;;;;45049:15;-1:-1:-1;;;45024:21:93;;;;;:40;;45004:60;45003:80;;45072:11;;;;45003:80;;;45068:1;44996:87;44874:216;-1:-1:-1;;;44874:216:93:o;28978:488::-;29151:6;:11;;29161:1;29151:11;29147:53;;29183:17;;-1:-1:-1;;;29183:17:93;;;;;;;;;;;29147:53;29252:6;:11;;29262:1;29252:11;29248:52;;29284:16;;-1:-1:-1;;;29284:16:93;;;;;;;;;;;29248:52;29378:15;29358:16;:35;;;29354:105;;29414:45;;-1:-1:-1;;;29414:45:93;;12647:12:137;12635:25;;29414:45:93;;;12617:44:137;12590:18;;29414:45:93;12473:194:137;29354:105:93;28978:488;;:::o;29588:592::-;29649:17;29669:13;;;:5;:13;;;;;29785:15;;-1:-1:-1;;29785:15:93;29799:1;29785:15;;;29880:26;29669:13;29880:20;:26::i;:::-;29853:24;;;:53;29916:24;;;:28;;-1:-1:-1;;;;29916:28:93;;;30141:32;;30164:6;;30141:32;;29943:1;;30141:32;29639:541;29588:592;:::o;3076:475:102:-;3157:23;3183:30;:5;3207:4;3183:15;:30::i;:::-;3157:56;-1:-1:-1;3224:46:102;:5;3248:6;3264:4;3224:23;:46::i;:::-;3280:224;3316:5;3352:15;3405:4;3445:6;3489:4;3280:14;:224::i;:::-;3537:6;-1:-1:-1;;;;;3520:24:102;;3530:5;3520:24;;;;;;:::i;:::-;;;;;;;;3147:404;3076:475;;:::o;3922:497::-;4008:23;4034:28;:5;4050:11;4034:15;:28::i;:::-;4008:54;-1:-1:-1;4073:55:102;:5;4109:4;4116:11;4073:27;:55::i;:::-;4138:229;4174:5;4210:15;4255:11;4309:4;4352;4138:14;:229::i;:::-;4400:11;-1:-1:-1;;;;;4383:29:102;;4393:5;4383:29;;;;;;:::i;17070:182:0:-;17168:4;17191:31;17206:5;17213:8;17191:14;:31::i;:::-;:54;;;;;17226:19;17239:5;17226:12;:19::i;18111:1230:93:-;18208:17;18228:13;;;:5;:13;;;;;;;;18513:16;;;;:29;;;;18491:18;;;;;-1:-1:-1;;;;;18491:18:93;;;:51;;;;;:95;;-1:-1:-1;18558:16:93;;;;:23;;;:28;18491:95;18474:155;;;18604:25;;-1:-1:-1;;;18604:25:93;;;;;;;;;;;18474:155;18755:20;;;;:29;18727:57;;;;;;;;:::i;:::-;:15;;;:24;;;:57;;;;;;;;:::i;:::-;;;:138;;;-1:-1:-1;18832:20:93;;;;:33;;;18800:15;;;:28;;;;-1:-1:-1;;;;;18800:28:93;;;:65;;;;18727:138;:199;;;-1:-1:-1;18903:20:93;;;;:23;;;18881:18;;;;:45;;18727:199;:268;;;-1:-1:-1;18968:20:93;;;;;:27;;18942:22;;;;:53;;18727:268;18710:332;;;19013:29;;-1:-1:-1;;;19013:29:93;;;;;;;;;;;18710:332;19145:18;;;;19128:13;;;;-1:-1:-1;;;;;19128:13:93;;;:35;;;19124:211;;19247:13;;;;19291:18;;;;19186:138;;-1:-1:-1;;;19186:138:93;;-1:-1:-1;;;;;19247:13:93;;;19186:138;;;17355:34:137;17425:15;;17405:18;;;17398:43;17290:18;;19186:138:93;17143:304:137;19526:922:93;19730:16;;19715:32;;-1:-1:-1;;;19715:32:93;;-1:-1:-1;;;;;678:32:137;;;19715::93;;;660:51:137;19642:14:93;;19715:9;:14;;;;633:18:137;;19715:32:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19799:17;19819:13;;;:5;:13;;;;;;;;19842:15;;19888:16;;;;:29;;;-1:-1:-1;;;;;19867:50:93;19842:15;19867:50;-1:-1:-1;;;;;;19867:50:93;;;;19856:1;19867:50;;;19706:41;;-1:-1:-1;19956:24:93;;;;:10;:24;:::i;:::-;19927:26;;;:53;;19990:45;20019:15;19990:45;;;-1:-1:-1;;;19990:45:93;-1:-1:-1;;;;;;19990:45:93;;;-1:-1:-1;;;;;19927:53:93;;;;19990:45;;;;;;;20095:18;;;;20069:44;;;;;;;;:::i;:::-;20045:21;;;;:68;;;;;;;-1:-1:-1;;;20045:68:93;-1:-1:-1;;;;20045:68:93;;;;;;;;;;20139:18;;;;20123:13;;;:34;;-1:-1:-1;;;;;20123:34:93;;;-1:-1:-1;;;;;;20123:34:93;;;;;;20189:16;;20167:19;;;;:38;;20242:29;;;;20215:56;;-1:-1:-1;;;20215:56:93;-1:-1:-1;;;;;;20215:56:93;;;20167:38;;;;20215:56;;;;;;;;;;20308:29;;;;20281:24;;;:56;20370:16;;;;:23;;;;;20347:20;;;:46;20421:20;;;20403:38;;:15;;;:38;;20421:20;;20403:15;;:38;;:15;;-1:-1:-1;;20403:38:93;;;;20045:21;20403:38;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;20403:38:93;;;;;;-1:-1:-1;;;;;20403:38:93;;;;;-1:-1:-1;;;;;;20403:38:93;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19526:922:93;;-1:-1:-1;;19526:922:93:o;20660:1145::-;20820:47;20826:9;:20;;;20848:9;:18;;;20820:5;:47::i;:::-;20955:16;;-1:-1:-1;;;;;20927:44:93;:24;;;;:10;:24;:::i;:::-;-1:-1:-1;;;;;20927:44:93;;20923:196;;21044:64;21068:9;:16;;;21086:9;21097:10;21044:23;:64::i;:::-;21182:17;21201:21;21238:74;21274:6;-1:-1:-1;;;;;21274:10:93;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21288:9;:16;;;:23;;;21238:35;:74::i;:::-;21439:16;;;;21181:131;;-1:-1:-1;21181:131:93;-1:-1:-1;21494:13:93;;21490:153;;21545:9;21523:12;:19;;:31;;;;;21568:64;21578:12;21592:9;:16;;;21610:6;-1:-1:-1;;;;;21610:19:93;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21568:9;:64::i;:::-;21692:19;;;:35;;;21761:16;;21779:18;;;;21737:61;;21692:12;;21737:9;:61::i;22367:3764::-;22528:17;22548:24;;;:5;:24;;;;;;22602:36;;-1:-1:-1;;;22602:36:93;;;;;868:25:137;;;22548:24:93;;22528:17;22602:9;-1:-1:-1;;;;;22602:17:93;;;;841:18:137;;22602:36:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22582:56;;22648:23;22674:38;22694:17;22674:19;:38::i;:::-;22648:64;;22776:17;22795:21;22832:74;22868:6;-1:-1:-1;;;;;22868:10:93;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22882:9;:16;;;:23;;;22832:35;:74::i;:::-;22775:131;;;;22917:14;22934:40;22943:15;22960:13;22934:8;:40::i;:::-;22917:57;;22984:15;23018;23002:13;:31;:69;;23070:1;23002:69;;;23036:31;23052:15;23036:13;:31;:::i;:::-;22984:87;;23081:16;23110:1;23100:7;:11;:49;;23118:31;23136:13;23118:15;:31;:::i;:::-;23100:49;;;23114:1;23100:49;23081:68;;23468:25;23528:9;-1:-1:-1;;;;;23508:29:93;:9;:16;;;-1:-1:-1;;;;;23508:29:93;;;:137;;;-1:-1:-1;23554:19:93;;;;-1:-1:-1;;;;;23554:32:93;;;:19;;:32;:90;;;;-1:-1:-1;23620:24:93;;;;:10;:24;:::i;:::-;23590:26;;;;-1:-1:-1;;;;;23590:26:93;;;:54;;;;23554:90;23772:16;;;;23876;;23468:177;;-1:-1:-1;23772:16:93;-1:-1:-1;;;;;23848:44:93;:24;;;;:10;:24;:::i;:::-;-1:-1:-1;;;;;23848:44:93;;23844:285;;24037:7;24000:20;:33;;24032:1;24000:33;;;24023:6;24000:33;23987:47;;:9;:47;:::i;:::-;:57;;;;:::i;:::-;23965:19;;;:79;24058:60;23965:12;24096:9;24107:10;24058:23;:60::i;:::-;24167:13;;24163:153;;24218:9;24196:12;:19;;:31;;;;;24241:64;24251:12;24265:9;:16;;;24283:6;-1:-1:-1;;;;;24283:19:93;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24241:64;24390:20;24386:130;;;24426:19;;;:28;;;24488:16;;24468:37;;24426:12;;24468:5;:37::i;:::-;24576:11;;24572:459;;24692:19;;;:29;;;24759:16;;24777:18;;;;24735:61;;24692:12;;24735:9;:61::i;:::-;24572:459;;;24817:12;;24813:218;;24937:19;;;:30;;;25001:18;;;;24981:39;;24937:12;;24981:5;:39::i;:::-;25078:4;:23;25124:17;25207:8;25170:20;:33;;25202:1;25170:33;;;25193:6;25170:33;25169:46;;;;:::i;:::-;25078:182;;-1:-1:-1;;;;;;25078:182:93;;;;;;;;;;19703:25:137;;;;19744:18;;;19737:34;-1:-1:-1;;;;;19807:32:137;;19787:18;;;19780:60;19676:18;;25078:182:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25074:1051;;25687:20;25682:433;;25727:19;;;:28;;;25805:16;;-1:-1:-1;;;;;25777:44:93;:24;;;;:10;:24;:::i;:::-;-1:-1:-1;;;;;25777:44:93;;25773:273;;25967:60;25991:12;26005:9;26016:10;25967:23;:60::i;:::-;26063:37;26069:12;26083:9;:16;;;26063:5;:37::i;:::-;22518:3613;;;;;;;;;;22367:3764;;;:::o;36728:114::-;36783:22;;-1:-1:-1;;;36783:22:93;;;;;868:25:137;;;36783:9:93;-1:-1:-1;;;;;36783:14:93;;;;841:18:137;;36783:22:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;36822:13:93;;;;-1:-1:-1;36822:5:93;:13;;;;;;;36815:20;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;-1:-1:-1;;;;;;36815:20:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36728:114::o;6865:714:102:-;6993:23;7019:30;:5;7043:4;7019:15;:30::i;:::-;6993:56;-1:-1:-1;7060:60:102;:5;7092:4;7107:11;7060:23;:60::i;:::-;7162:18;;;;7182:12;;;;7130:65;;-1:-1:-1;;;7130:65:102;;-1:-1:-1;;;;;32434:15:137;;;7130:65:102;;;32416:34:137;32486:15;;;32466:18;;;32459:43;32538:15;;;32518:18;;;32511:43;32570:18;;;32563:34;;;;7130:18:102;;;;;;32350:19:137;;7130:65:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7205:223;7241:5;7277:15;7330:4;7370;7412:5;7205:14;:223::i;:::-;7566:5;-1:-1:-1;;;;;7520:52:102;7560:4;-1:-1:-1;;;;;7520:52:102;7546:11;-1:-1:-1;;;;;7520:52:102;;7531:5;7520:52;;;;;;:::i;:::-;;;;;;;;6983:596;6865:714;;;;:::o;6598:232:65:-;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:65;6598:232;-1:-1:-1;;;;;6598:232:65:o;14248:722:0:-;14326:7;;14349:14;;:32;;;;;;;;:::i;:::-;;14345:619;;14411:18;;;;14404:44;;-1:-1:-1;;;14404:44:0;;-1:-1:-1;;;;;678:32:137;;;14404:44:0;;;660:51:137;14404:36:0;;;;;;633:18:137;;14404:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14397:51;;;;14345:619;14488:15;14470:14;;:33;;;;;;;;:::i;:::-;;14466:498;;14575:6;-1:-1:-1;;;;;14526:55:0;14534:5;:18;;;-1:-1:-1;;;;;14526:35:0;;14562:5;:8;;;14526:45;;;;;;;;;;;;;868:25:137;;856:2;841:18;;722:177;14526:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14526:55:0;;:63;;14588:1;14526:63;;;14584:1;14526:63;14519:70;;;;;;14466:498;14629:16;14611:14;;:34;;;;;;;;:::i;:::-;;14607:357;;14677:18;;;;14715:8;;;;;14668:56;;-1:-1:-1;;;14668:56:0;;-1:-1:-1;;;;;15703:32:137;;;14668:56:0;;;15685:51:137;15752:18;;;15745:34;;;;14668:38:0;;;;;15658:18:137;;14668:56:0;15511:274:137;14607:357:0;14764:22;14746:14;;:40;;;;;;;;:::i;:::-;;14742:222;;14865:6;-1:-1:-1;;;;;14809:62:0;14824:5;:18;;;-1:-1:-1;;;;;14809:42:0;;14852:5;:8;;;14809:52;;;;;;;;;;;;;868:25:137;;856:2;841:18;;722:177;14742:222:0;14911:42;;-1:-1:-1;;;14911:42:0;;32810:2:137;14911:42:0;;;32792:21:137;;;32829:18;;;32822:30;32888:34;32868:18;;;32861:62;32940:18;;14911:42:0;32608:356:137;5635:152:0;5735:45;5754:5;5761:6;5769:4;5775;5735:18;:45::i;7585:668:102:-;7838:19;-1:-1:-1;;;;;7820:37:102;:14;-1:-1:-1;;;;;7820:37:102;;7816:138;;7880:63;;-1:-1:-1;;;7880:63:102;;-1:-1:-1;;;;;678:32:137;;7880:63:102;;;660:51:137;633:18;;7880:63:102;497:220:137;7816:138:102;7964:23;7990:22;:138;;8103:25;:5;:23;:25::i;:::-;8085:43;;:15;:43;:::i;:::-;7990:138;;;8045:25;:5;:23;:25::i;:::-;8027:43;;:15;:43;:::i;:::-;7964:164;-1:-1:-1;8162:31:102;:5;8178:14;8162:15;:31::i;:::-;8143:15;:50;8139:108;;8216:20;;-1:-1:-1;;;8216:20:102;;;;;;;;;;;1667:4213:70;1749:14;;;-1:-1:-1;;2286:1:70;2283;2276:20;2329:1;2326;2322:9;2313:18;;2384:5;2380:2;2377:13;2369:5;2365:2;2361:14;2357:34;2348:43;;;2486:5;2495:1;2486:10;2482:368;;2824:11;2816:5;:19;;;;;:::i;:::-;;2809:26;;;;;;2482:368;2974:5;2960:11;:19;2952:53;;;;-1:-1:-1;;;2952:53:70;;33171:2:137;2952:53:70;;;33153:21:137;33210:2;33190:18;;;33183:30;-1:-1:-1;;;33229:18:137;;;33222:51;33290:18;;2952:53:70;32969:345:137;2952:53:70;3261:17;3396:11;3393:1;3390;3383:25;4774:1;3944;3929:12;;:16;;3914:32;;4049:22;;;;4755:1;:15;;4754:21;;5007;;;5003:25;;4992:36;5076:21;;;5072:25;;5061:36;5146:21;;;5142:25;;5131:36;5216:21;;;5212:25;;5201:36;5286:21;;;5282:25;;5271:36;5357:21;;;5353:25;;;5342:36;;;3899:12;4294;;;4290:23;;;4286:31;;;3510:20;;;3499:32;;;4406:12;;;;3557:21;;4147:16;;;;4397:21;;;;5821:15;;;-1:-1:-1;;;;1667:4213:70:o;5077:149:0:-;5173:46;5192:5;5199:6;5207:4;5213:5;5173:18;:46::i;18426:428::-;18667:18;;;;18634:52;;-1:-1:-1;;;18634:52:0;;-1:-1:-1;;;;;678:32:137;;;18634:52:0;;;660:51:137;18531:4:0;;;;18634:32;;;;;;633:18:137;;18634:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18612:74;-1:-1:-1;1293:15:0;18700:40;;;;18696:103;;18767:14;;18761:38;;;;:21;;;;;;;;:::i;:::-;:38;;;18754:45;;;;;18696:103;18817:30;18841:5;18817:23;:30::i;21578:735::-;21643:4;;21663:14;;:32;;;;;;;;:::i;:::-;;21659:626;;21753:8;;;;:13;21749:31;;-1:-1:-1;21775:5:0;;21578:735;-1:-1:-1;21578:735:0:o;21749:31::-;21659:626;;;21820:15;21802:14;;:33;;;;;;;;:::i;:::-;;21798:487;;21898:12;;;;:17;21894:35;;-1:-1:-1;21924:5:0;;21578:735;-1:-1:-1;21578:735:0:o;21798:487::-;21969:16;21951:14;;:34;;;;;;;;:::i;:::-;21947:338;;;22070:22;22052:14;;:40;;;;;;;;:::i;:::-;;22048:237;;22162:12;;;;:17;22158:35;;-1:-1:-1;22188:5:0;;21578:735;-1:-1:-1;21578:735:0:o;22048:237::-;22258:14;;22252:21;;;;;;;;:::i;:::-;22232:42;;-1:-1:-1;;;22232:42:0;;33769:4:137;33757:17;;;22232:42:0;;;33739:36:137;33712:18;;22232:42:0;33597:184:137;22048:237:0;-1:-1:-1;22302:4:0;;21578:735;-1:-1:-1;21578:735:0:o;26453:536:93:-;26622:24;-1:-1:-1;;;;;26649:6:93;:21;;26671:24;;;;:10;:24;:::i;:::-;26649:47;;-1:-1:-1;;;;;;26649:47:93;;;;;;;-1:-1:-1;;;;;678:32:137;;;26649:47:93;;;660:51:137;633:18;;26649:47:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26622:74;-1:-1:-1;;;;;;26710:34:93;;26706:137;;26805:24;;;;:10;:24;:::i;:::-;26767:65;;-1:-1:-1;;;26767:65:93;;-1:-1:-1;;;;;678:32:137;;;26767:65:93;;;660:51:137;633:18;;26767:65:93;497:220:137;26706:137:93;26857:13;;;;:17;26853:130;;26890:82;26908:6;26916:11;26929:24;;;;:10;:24;:::i;:::-;26955:16;;26890:17;:82::i;:::-;26612:377;26453:536;;;:::o;671:294:91:-;754:17;773:21;810:3;:8;;817:1;810:8;806:48;;-1:-1:-1;840:1:91;;-1:-1:-1;843:10:91;832:22;;806:48;877:33;889:10;901:3;877:33;;906:3;877:11;:33::i;:::-;865:45;-1:-1:-1;936:22:91;865:45;936:10;:22;:::i;:::-;920:38;;671:294;;;;;;:::o;588:104:70:-;646:7;676:1;672;:5;:13;;684:1;672:13;;;-1:-1:-1;680:1:70;;588:104;-1:-1:-1;588:104:70:o;5009:1456:65:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:65;;-1:-1:-1;6123:30:65;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;34013:25:137;;;34086:4;34074:17;;34054:18;;;34047:45;;;;34108:18;;;34101:34;;;34151:18;;;34144:34;;;6276:24:65;;33985:19:137;;6276:24:65;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:65;;-1:-1:-1;;6276:24:65;;;-1:-1:-1;;;;;;;6314:20:65;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:65;;-1:-1:-1;5009:1456:65;;;;;;;;:::o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:65;;34391:2:137;788:34:65;;;34373:21:137;34430:2;34410:18;;;34403:30;34469:26;34449:18;;;34442:54;34513:18;;788:34:65;34189:348:137;730:345:65;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:65;;34744:2:137;903:41:65;;;34726:21:137;34783:2;34763:18;;;34756:30;34822:33;34802:18;;;34795:61;34873:18;;903:41:65;34542:355:137;839:236:65;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:65;;35104:2:137;1020:44:65;;;35086:21:137;35143:2;35123:18;;;35116:30;35182:34;35162:18;;;35155:62;-1:-1:-1;;;35233:18:137;;;35226:32;35275:19;;1020:44:65;34902:398:137;5793:1204:0;5924:14;5906;;:32;;;;;;;;:::i;:::-;;5902:1089;;5976:4;-1:-1:-1;;;;;5958:23:0;;;5954:210;;5999:59;6039:4;6045:5;:12;;;6006:5;:18;;;-1:-1:-1;;;;;5999:39:0;;;:59;;;;;:::i;:::-;5902:1089;;5954:210;6093:71;6137:6;6145:4;6151:5;:12;;;6100:5;:18;;;-1:-1:-1;;;;;6093:43:0;;;:71;;;;;;:::i;5902:1089::-;6204:15;6186:14;;:33;;;;;;;;:::i;:::-;;6182:809;;6240:6;6235:200;;6272:18;;;;6319:8;;;;;6264:64;;-1:-1:-1;;;6264:64:0;;-1:-1:-1;;;;;35563:15:137;;;6264:64:0;;;35545:34:137;35615:15;;;35595:18;;;35588:43;35647:18;;;35640:34;;;;6264:40:0;;;;;35480:18:137;;6264:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6182:809;;6235:200;6371:18;;;;6422:8;;;;;6363:72;;-1:-1:-1;;;6363:72:0;;-1:-1:-1;;;;;36008:15:137;;;6363:72:0;;;35990:34:137;36060:15;;;36040:18;;;36033:43;36092:18;;;36085:34;;;;36155:3;36135:18;;;36128:31;-1:-1:-1;36175:19:137;;;36168:30;6363:44:0;;;;;36215:19:137;;6363:72:0;35685:555:137;6182:809:0;6475:16;6457:14;;:34;;;;;;;;:::i;:::-;;6453:538;;6516:5;:18;;;-1:-1:-1;;;;;6507:45:0;;6553:6;6561:4;6567:5;:8;;;6577:5;:12;;;6593:1;6577:17;:36;;6601:5;:12;;;6577:36;;;6597:1;6577:36;6507:111;;-1:-1:-1;;;;;;6507:111:0;;;;;;;-1:-1:-1;;;;;36596:15:137;;;6507:111:0;;;36578:34:137;36648:15;;;;36628:18;;;36621:43;36680:18;;;36673:34;36723:18;;;36716:34;36558:3;36766:19;;;36759:32;-1:-1:-1;36807:19:137;;;36800:30;36847:19;;6507:111:0;36245:627:137;6453:538:0;6658:22;6640:14;;:40;;;;;;;;:::i;:::-;;6636:355;;6718:4;-1:-1:-1;;;;;6700:23:0;;;6696:210;;6756:18;;;;6791:8;;;;;6741:59;;-1:-1:-1;;;6741:59:0;;-1:-1:-1;;;;;15703:32:137;;;6741:59:0;;;15685:51:137;15752:18;;;15745:34;;;;6741:43:0;;;;;15658:18:137;;6741:59:0;15511:274:137;6696:210:0;6850:18;;;;6897:8;;;;;6835:71;;-1:-1:-1;;;6835:71:0;;-1:-1:-1;;;;;35563:15:137;;;6835:71:0;;;35545:34:137;35615:15;;;35595:18;;;35588:43;35647:18;;;35640:34;;;;6835:47:0;;;;;35480:18:137;;6835:71:0;35305:375:137;7478:382:0;7548:7;;7571:14;;:32;;;;;;;;:::i;:::-;;7567:286;;-1:-1:-1;7624:12:0;;;;7478:382::o;7567:286::-;7673:16;7655:14;;:34;;;;;;;;:::i;:::-;;:54;;;;;7708:1;7693:5;:12;;;:16;7655:54;7651:202;;;-1:-1:-1;7730:12:0;;;;7478:382::o;7651:202::-;7478:382;;;:::o;19179:2028::-;19255:4;;19275:14;;:32;;;;;;;;:::i;:::-;;19271:1930;;19383:35;:5;:18;;;-1:-1:-1;;;;;19383:33:0;;:35::i;:::-;19379:1184;;;19563:18;;;;:71;;-1:-1:-1;;;;;19563:51:0;-1:-1:-1;;;19563:51:0;:71::i;:::-;19559:108;;;-1:-1:-1;19663:4:0;;19179:2028;-1:-1:-1;19179:2028:0:o;19559:108::-;19840:18;;;;:72;;-1:-1:-1;;;;;19840:51:0;-1:-1:-1;;;19840:51:0;:72::i;:::-;19839:73;:171;;;;-1:-1:-1;19937:18:0;;;;:73;;-1:-1:-1;;;;;19937:51:0;-1:-1:-1;;;19937:51:0;:73::i;:::-;19936:74;19839:171;:276;;;;-1:-1:-1;20035:18:0;;;;:80;;-1:-1:-1;;;;;20035:51:0;-1:-1:-1;;;20035:51:0;:80::i;:::-;20034:81;19812:303;19179:2028;-1:-1:-1;;19179:2028:0:o;19379:1184::-;-1:-1:-1;20514:18:0;;;-1:-1:-1;;;;;20514:30:0;;:34;;;19179:2028::o;19271:1930::-;20602:15;20584:14;;:33;;;;;;;;:::i;:::-;;20580:621;;20679:18;;;;:57;;-1:-1:-1;;;;;20679:36:0;-1:-1:-1;;;20679:36:0;:57::i;20580:621::-;20776:16;20758:14;;:34;;;;;;;;:::i;:::-;;20754:447;;20855:18;;;;:58;;-1:-1:-1;;;;;20855:36:0;-1:-1:-1;;;20855:36:0;:58::i;20754:447::-;20953:22;20935:14;;:40;;;;;;;;:::i;:::-;;20931:270;;21044:18;;;;:65;;-1:-1:-1;;;;;21044:36:0;-1:-1:-1;;;21044:36:0;:65::i;5795:559:102:-;5927:23;5953:22;:5;5969;5953:15;:22::i;:::-;6020:18;;;;6040:12;;;;5986:67;;-1:-1:-1;;;5986:67:102;;-1:-1:-1;;;;;32434:15:137;;;5986:67:102;;;32416:34:137;32486:15;;;32466:18;;;32459:43;32538:15;;;32518:18;;;32511:43;32570:18;;;32563:34;;;;5927:48:102;;-1:-1:-1;5986:20:102;;;;;32350:19:137;;5986:67:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6063:214;6099:5;6135:15;6180:5;6220:4;6262;6063:14;:214::i;:::-;6341:5;-1:-1:-1;;;;;6293:54:102;6335:4;-1:-1:-1;;;;;6293:54:102;6321:11;-1:-1:-1;;;;;6293:54:102;;6306:5;6293:54;;;;;;:::i;941:175:55:-;1050:58;;-1:-1:-1;;;;;15703:32:137;;1050:58:55;;;15685:51:137;15752:18;;;15745:34;;;1023:86:55;;1043:5;;-1:-1:-1;;;1073:23:55;15658:18:137;;1050:58:55;;;;-1:-1:-1;;1050:58:55;;;;;;;;;;;;;;-1:-1:-1;;;;;1050:58:55;-1:-1:-1;;;;;;1050:58:55;;;;;;;;;;1023:19;:86::i;1355:203::-;1482:68;;-1:-1:-1;;;;;35563:15:137;;;1482:68:55;;;35545:34:137;35615:15;;35595:18;;;35588:43;35647:18;;;35640:34;;;1455:96:55;;1475:5;;-1:-1:-1;;;1505:27:55;35480:18:137;;1482:68:55;35305:375:137;704:427:68;768:4;975:68;1008:7;-1:-1:-1;;;975:32:68;:68::i;:::-;:149;;;;-1:-1:-1;1060:64:68;1093:7;-1:-1:-1;;;;;;4421:647:68;4592:71;;;-1:-1:-1;;;;;;3254:33:137;;4592:71:68;;;;3236:52:137;;;;4592:71:68;;;;;;;;;;3209:18:137;;;;4592:71:68;;;;;;;;;-1:-1:-1;;;;;4592:71:68;-1:-1:-1;;;4592:71:68;;;4871:20;;4523:4;;4592:71;4523:4;;;;;;4592:71;4523:4;;4871:20;4836:7;4829:5;4818:86;4807:97;;4931:16;4917:30;;4981:4;4975:11;4960:26;;5013:7;:29;;;;;5038:4;5024:10;:18;;5013:29;:48;;;;;5060:1;5046:11;:15;5013:48;5006:55;4421:647;-1:-1:-1;;;;;;;4421:647:68:o;1349:282::-;1436:4;1543:23;1558:7;1543:14;:23::i;:::-;:81;;;;;1570:54;1603:7;1612:11;1570:32;:54::i;5196:642:55:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;-1:-1:-1;;;;;5641:27:55;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:55;;37079:2:137;5720:111:55;;;37061:21:137;37118:2;37098:18;;;37091:30;37157:34;37137:18;;;37130:62;-1:-1:-1;;;37208:18:137;;;37201:40;37258:19;;5720:111:55;36877:406:137;4108:223:60;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4241;5446;5460:23;5487:6;-1:-1:-1;;;;;5487:11:60;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;7851;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;-1:-1:-1;;;;;1702:19:60;;;8113:60;;;;-1:-1:-1;;;8113:60:60;;37897:2:137;8113:60:60;;;37879:21:137;37936:2;37916:18;;;37909:30;37975:31;37955:18;;;37948:59;38024:18;;8113:60:60;37695:353:137;8113:60:60;-1:-1:-1;8208:10:60;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:60;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:286:137:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:137;;209:43;;199:71;;266:1;263;256:12;904:180;963:6;1016:2;1004:9;995:7;991:23;987:32;984:52;;;1032:1;1029;1022:12;984:52;-1:-1:-1;1055:23:137;;904:180;-1:-1:-1;904:180:137:o;1089:250::-;1174:1;1184:113;1198:6;1195:1;1192:13;1184:113;;;1274:11;;;1268:18;1255:11;;;1248:39;1220:2;1213:10;1184:113;;;-1:-1:-1;;1331:1:137;1313:16;;1306:27;1089:250::o;1344:271::-;1386:3;1424:5;1418:12;1451:6;1446:3;1439:19;1467:76;1536:6;1529:4;1524:3;1520:14;1513:4;1506:5;1502:16;1467:76;:::i;:::-;1597:2;1576:15;-1:-1:-1;;1572:29:137;1563:39;;;;1604:4;1559:50;;1344:271;-1:-1:-1;;1344:271:137:o;1620:220::-;1769:2;1758:9;1751:21;1732:4;1789:45;1830:2;1819:9;1815:18;1807:6;1789:45;:::i;1845:131::-;-1:-1:-1;;;;;1920:31:137;;1910:42;;1900:70;;1966:1;1963;1956:12;1981:347;2032:8;2042:6;2096:3;2089:4;2081:6;2077:17;2073:27;2063:55;;2114:1;2111;2104:12;2063:55;-1:-1:-1;2137:20:137;;-1:-1:-1;;;;;2169:30:137;;2166:50;;;2212:1;2209;2202:12;2166:50;2249:4;2241:6;2237:17;2225:29;;2301:3;2294:4;2285:6;2277;2273:19;2269:30;2266:39;2263:59;;;2318:1;2315;2308:12;2333:754;2430:6;2438;2446;2454;2462;2515:3;2503:9;2494:7;2490:23;2486:33;2483:53;;;2532:1;2529;2522:12;2483:53;2571:9;2558:23;2590:31;2615:5;2590:31;:::i;:::-;2640:5;-1:-1:-1;2697:2:137;2682:18;;2669:32;2710:33;2669:32;2710:33;:::i;:::-;2762:7;-1:-1:-1;2816:2:137;2801:18;;2788:32;;-1:-1:-1;2871:2:137;2856:18;;2843:32;-1:-1:-1;;;;;2887:30:137;;2884:50;;;2930:1;2927;2920:12;2884:50;2969:58;3019:7;3010:6;2999:9;2995:22;2969:58;:::i;:::-;2333:754;;;;-1:-1:-1;2333:754:137;;-1:-1:-1;3046:8:137;;2943:84;2333:754;-1:-1:-1;;;2333:754:137:o;3299:166::-;3369:5;3414:3;3405:6;3400:3;3396:16;3392:26;3389:46;;;3431:1;3428;3421:12;3389:46;-1:-1:-1;3453:6:137;3299:166;-1:-1:-1;3299:166:137:o;3470:558::-;3587:6;3595;3603;3656:3;3644:9;3635:7;3631:23;3627:33;3624:53;;;3673:1;3670;3663:12;3624:53;3696:64;3752:7;3741:9;3696:64;:::i;:::-;3686:74;;3811:3;3800:9;3796:19;3783:33;-1:-1:-1;;;;;3831:6:137;3828:30;3825:50;;;3871:1;3868;3861:12;3825:50;3910:58;3960:7;3951:6;3940:9;3936:22;3910:58;:::i;:::-;3470:558;;3987:8;;-1:-1:-1;3884:84:137;;-1:-1:-1;;;;3470:558:137:o;4439:260::-;4536:6;4589:3;4577:9;4568:7;4564:23;4560:33;4557:53;;;4606:1;4603;4596:12;4557:53;4629:64;4685:7;4674:9;4629:64;:::i;4910:127::-;4971:10;4966:3;4962:20;4959:1;4952:31;5002:4;4999:1;4992:15;5026:4;5023:1;5016:15;5042:454;5117:5;5111:12;5149:1;5145:2;5142:9;5132:140;;5194:10;5189:3;5185:20;5182:1;5175:31;5229:4;5226:1;5219:15;5257:4;5254:1;5247:15;5132:140;5281:15;;5349:4;5338:16;;;5332:23;-1:-1:-1;;;;;5328:49:137;5312:14;;;5305:73;5427:4;5416:16;;;5410:23;5394:14;;;5387:47;5483:4;5472:16;;;5466:23;5450:14;;5443:47;5042:454::o;5501:1231::-;6062:4;6050:17;;6032:36;;6087:12;6135:15;;;6130:2;6115:18;;6108:43;6187:15;;6182:2;6167:18;;6160:43;-1:-1:-1;;;;;6277:15:137;;;6272:2;6257:18;;6250:43;6330:15;;;6324:3;6309:19;;6302:44;6383:15;;6230:3;6362:19;;6355:44;6448:8;6436:21;;6430:3;6415:19;;6408:50;6489:3;6474:19;;6467:35;;;6019:3;6004:19;;6511:52;6558:3;6543:19;;6535:6;6511:52;:::i;:::-;6572;6619:3;6608:9;6604:19;6596:6;6572:52;:::i;:::-;-1:-1:-1;;;;;4770:31:137;;;;6676:3;6661:19;;4758:44;6712:3;6697:19;6690:36;5501:1231;;-1:-1:-1;;;;;;;;;;5501:1231:137:o;7166:127::-;7227:10;7222:3;7218:20;7215:1;7208:31;7258:4;7255:1;7248:15;7282:4;7279:1;7272:15;7298:250;7365:2;7359:9;7407:6;7395:19;;-1:-1:-1;;;;;7429:34:137;;7465:22;;;7426:62;7423:88;;;7491:18;;:::i;:::-;7527:2;7520:22;7298:250;:::o;7553:107::-;7634:1;7627:5;7624:12;7614:40;;7650:1;7647;7640:12;7665:780;7745:6;7798:3;7786:9;7777:7;7773:23;7769:33;7766:53;;;7815:1;7812;7805:12;7766:53;7848:2;7842:9;7890:3;7882:6;7878:16;7960:6;7948:10;7945:22;-1:-1:-1;;;;;7912:10:137;7909:34;7906:62;7903:88;;;7971:18;;:::i;:::-;8007:2;8000:22;8044:23;;8076:37;8044:23;8076:37;:::i;:::-;8122:21;;8195:2;8180:18;;8167:32;8208:33;8167:32;8208:33;:::i;:::-;8269:2;8257:15;;8250:32;8343:2;8328:18;;;8315:32;8298:15;;;8291:57;8409:2;8394:18;;;8381:32;8364:15;;;8357:57;;;;-1:-1:-1;8261:6:137;7665:780;-1:-1:-1;7665:780:137:o;8450:158::-;8513:5;8558:2;8549:6;8544:3;8540:16;8536:25;8533:45;;;8574:1;8571;8564:12;8613:996;8805:6;8813;8821;8829;8837;8881:9;8872:7;8868:23;8911:3;8907:2;8903:12;8900:32;;;8928:1;8925;8918:12;8900:32;8968:9;8955:23;-1:-1:-1;;;;;9038:2:137;9030:6;9027:14;9024:34;;;9054:1;9051;9044:12;9024:34;9077:22;;;;9133:3;9115:16;;;9111:26;9108:46;;;9150:1;9147;9140:12;9108:46;9173:2;9163:12;;9194:66;9252:7;9247:2;9236:9;9232:18;9194:66;:::i;:::-;9184:76;-1:-1:-1;9294:2:137;-1:-1:-1;;9276:16:137;;9272:25;9269:45;;;9310:1;9307;9300:12;9269:45;9348:2;9337:9;9333:18;9323:28;;9404:3;9393:9;9389:19;9376:33;9360:49;;9434:2;9424:8;9421:16;9418:36;;;9450:1;9447;9440:12;9418:36;;;9489:60;9541:7;9530:8;9519:9;9515:24;9489:60;:::i;10137:383::-;10214:6;10222;10230;10283:2;10271:9;10262:7;10258:23;10254:32;10251:52;;;10299:1;10296;10289:12;10251:52;10335:9;10322:23;10312:33;;10392:2;10381:9;10377:18;10364:32;10354:42;;10446:2;10435:9;10431:18;10418:32;10459:31;10484:5;10459:31;:::i;:::-;10509:5;10499:15;;;10137:383;;;;;:::o;10758:367::-;10821:8;10831:6;10885:3;10878:4;10870:6;10866:17;10862:27;10852:55;;10903:1;10900;10893:12;10852:55;-1:-1:-1;10926:20:137;;-1:-1:-1;;;;;10958:30:137;;10955:50;;;11001:1;10998;10991:12;10955:50;11038:4;11030:6;11026:17;11014:29;;11098:3;11091:4;11081:6;11078:1;11074:14;11066:6;11062:27;11058:38;11055:47;11052:67;;;11115:1;11112;11105:12;11130:1338;11290:6;11298;11306;11314;11322;11330;11338;11346;11399:3;11387:9;11378:7;11374:23;11370:33;11367:53;;;11416:1;11413;11406:12;11367:53;11455:9;11442:23;11474:31;11499:5;11474:31;:::i;:::-;11524:5;-1:-1:-1;11581:2:137;11566:18;;11553:32;11594:33;11553:32;11594:33;:::i;:::-;11646:7;-1:-1:-1;11704:2:137;11689:18;;11676:32;-1:-1:-1;;;;;11757:14:137;;;11754:34;;;11784:1;11781;11774:12;11754:34;11823:70;11885:7;11876:6;11865:9;11861:22;11823:70;:::i;:::-;11912:8;;-1:-1:-1;11797:96:137;-1:-1:-1;12000:2:137;11985:18;;11972:32;;-1:-1:-1;12016:16:137;;;12013:36;;;12045:1;12042;12035:12;12013:36;12084:72;12148:7;12137:8;12126:9;12122:24;12084:72;:::i;:::-;12175:8;;-1:-1:-1;12058:98:137;-1:-1:-1;12263:3:137;12248:19;;12235:33;;-1:-1:-1;12280:16:137;;;12277:36;;;12309:1;12306;12299:12;12277:36;;12348:60;12400:7;12389:8;12378:9;12374:24;12348:60;:::i;:::-;11130:1338;;;;-1:-1:-1;11130:1338:137;;-1:-1:-1;11130:1338:137;;;;;;12427:8;-1:-1:-1;;;11130:1338:137:o;12672:245::-;12762:6;12815:2;12803:9;12794:7;12790:23;12786:32;12783:52;;;12831:1;12828;12821:12;12783:52;12854:57;12903:7;12892:9;12854:57;:::i;12922:823::-;13028:6;13036;13044;13052;13060;13068;13121:3;13109:9;13100:7;13096:23;13092:33;13089:53;;;13138:1;13135;13128:12;13089:53;13177:9;13164:23;13196:31;13221:5;13196:31;:::i;:::-;13246:5;-1:-1:-1;13303:2:137;13288:18;;13275:32;13316:33;13275:32;13316:33;:::i;:::-;13368:7;-1:-1:-1;13422:2:137;13407:18;;13394:32;;-1:-1:-1;13473:2:137;13458:18;;13445:32;;-1:-1:-1;13528:3:137;13513:19;;13500:33;-1:-1:-1;;;;;13545:30:137;;13542:50;;;13588:1;13585;13578:12;13542:50;13627:58;13677:7;13668:6;13657:9;13653:22;13627:58;:::i;:::-;12922:823;;;;-1:-1:-1;12922:823:137;;-1:-1:-1;12922:823:137;;13704:8;;12922:823;-1:-1:-1;;;12922:823:137:o;13750:138::-;13829:13;;13851:31;13829:13;13851:31;:::i;13893:251::-;13963:6;14016:2;14004:9;13995:7;13991:23;13987:32;13984:52;;;14032:1;14029;14022:12;13984:52;14064:9;14058:16;14083:31;14108:5;14083:31;:::i;14357:897::-;14437:6;14490:2;14478:9;14469:7;14465:23;14461:32;14458:52;;;14506:1;14503;14496:12;14458:52;14539:9;14533:16;-1:-1:-1;;;;;14609:2:137;14601:6;14598:14;14595:34;;;14625:1;14622;14615:12;14595:34;14663:6;14652:9;14648:22;14638:32;;14708:7;14701:4;14697:2;14693:13;14689:27;14679:55;;14730:1;14727;14720:12;14679:55;14759:2;14753:9;14781:2;14777;14774:10;14771:36;;;14787:18;;:::i;:::-;14862:2;14856:9;14830:2;14916:13;;-1:-1:-1;;14912:22:137;;;14936:2;14908:31;14904:40;14892:53;;;14960:18;;;14980:22;;;14957:46;14954:72;;;15006:18;;:::i;:::-;15046:10;15042:2;15035:22;15081:2;15073:6;15066:18;15121:7;15116:2;15111;15107;15103:11;15099:20;15096:33;15093:53;;;15142:1;15139;15132:12;15093:53;15155:68;15220:2;15215;15207:6;15203:15;15198:2;15194;15190:11;15155:68;:::i;15259:247::-;15318:6;15371:2;15359:9;15350:7;15346:23;15342:32;15339:52;;;15387:1;15384;15377:12;15339:52;15426:9;15413:23;15445:31;15470:5;15445:31;:::i;15790:165::-;15857:20;;15917:12;15906:24;;15896:35;;15886:63;;15945:1;15942;15935:12;15960:184;16018:6;16071:2;16059:9;16050:7;16046:23;16042:32;16039:52;;;16087:1;16084;16077:12;16039:52;16110:28;16128:9;16110:28;:::i;16770:118::-;16856:5;16849:13;16842:21;16835:5;16832:32;16822:60;;16878:1;16875;16868:12;16893:245;16960:6;17013:2;17001:9;16992:7;16988:23;16984:32;16981:52;;;17029:1;17026;17019:12;16981:52;17061:9;17055:16;17080:28;17102:5;17080:28;:::i;17723:127::-;17784:10;17779:3;17775:20;17772:1;17765:31;17815:4;17812:1;17805:15;17839:4;17836:1;17829:15;17855:174;17922:12;17954:10;;;17966;;;17950:27;;17989:11;;;17986:37;;;18003:18;;:::i;:::-;17986:37;17855:174;;;;:::o;18332:125::-;18397:9;;;18418:10;;;18415:36;;;18431:18;;:::i;18462:1034::-;18701:20;;18683:39;;18670:3;18655:19;;18769:4;18757:17;;18744:31;18784;18744;18784;:::i;:::-;-1:-1:-1;;;;;18853:31:137;18846:4;18831:20;;18824:61;18948:4;18936:17;;;18923:31;18901:20;;;18894:61;18984:36;19014:4;19002:17;;18984:36;:::i;:::-;19039:12;19107:2;19093:12;19089:21;19082:4;19071:9;19067:20;19060:51;19191:2;19153:36;19183:4;19175:6;19171:17;19153:36;:::i;:::-;19149:45;19142:4;19131:9;19127:20;19120:75;;;19244:4;19236:6;19232:17;19219:31;19259:33;19284:7;19259:33;:::i;:::-;-1:-1:-1;;;;;4770:31:137;;19344:4;19329:20;;4758:44;19301:49;19413:4;19405:6;19401:17;19388:31;19381:4;19370:9;19366:20;19359:61;19483:4;19475:6;19471:17;19458:31;19451:4;19440:9;19436:20;19429:61;18462:1034;;;;:::o;19851:359::-;20038:6;20033:3;20026:19;20008:3;20074:6;20068:13;20090:73;20156:6;20151:2;20146:3;20142:12;20137:2;20129:6;20125:15;20090:73;:::i;:::-;20183:16;;;;20201:2;20179:25;;19851:359;-1:-1:-1;;;19851:359:137:o;20612:241::-;20668:6;20721:2;20709:9;20700:7;20696:23;20692:32;20689:52;;;20737:1;20734;20727:12;20689:52;20776:9;20763:23;20795:28;20817:5;20795:28;:::i;21137:521::-;21214:4;21220:6;21280:11;21267:25;21374:2;21370:7;21359:8;21343:14;21339:29;21335:43;21315:18;21311:68;21301:96;;21393:1;21390;21383:12;21301:96;21420:33;;21472:20;;;-1:-1:-1;;;;;;21504:30:137;;21501:50;;;21547:1;21544;21537:12;21501:50;21580:4;21568:17;;-1:-1:-1;21611:14:137;21607:27;;;21597:38;;21594:58;;;21648:1;21645;21638:12;21663:545;21756:4;21762:6;21822:11;21809:25;21916:2;21912:7;21901:8;21885:14;21881:29;21877:43;21857:18;21853:68;21843:96;;21935:1;21932;21925:12;21843:96;21962:33;;22014:20;;;-1:-1:-1;;;;;;22046:30:137;;22043:50;;;22089:1;22086;22079:12;22043:50;22122:4;22110:17;;-1:-1:-1;22173:1:137;22169:14;;;22153;22149:35;22139:46;;22136:66;;;22198:1;22195;22188:12;22213:266;22301:6;22296:3;22289:19;22353:6;22346:5;22339:4;22334:3;22330:14;22317:43;-1:-1:-1;22405:1:137;22380:16;;;22398:4;22376:27;;;22369:38;;;;22461:2;22440:15;;;-1:-1:-1;;22436:29:137;22427:39;;;22423:50;;22213:266::o;22484:979::-;22870:1;22866;22861:3;22857:11;22853:19;22845:6;22841:32;22830:9;22823:51;22910:6;22905:2;22894:9;22890:18;22883:34;22953:3;22948:2;22937:9;22933:18;22926:31;22804:4;22980:62;23037:3;23026:9;23022:19;23014:6;23006;22980:62;:::i;:::-;23078:22;;;23073:2;23058:18;;23051:50;23110:22;;;-1:-1:-1;;;;;23144:31:137;;23141:51;;;23188:1;23185;23178:12;23141:51;23222:6;23219:1;23215:14;23276:6;23268;23263:2;23255:6;23251:15;23238:45;23302:19;23362:18;;;23382:2;23358:27;;;23352:3;23337:19;;23330:56;23403:54;;23445:11;;23437:6;23429;23403:54;:::i;:::-;23395:62;22484:979;-1:-1:-1;;;;;;;;;;;22484:979:137:o;23468:167::-;23546:13;;23599:10;23588:22;;23578:33;;23568:61;;23625:1;23622;23615:12;23640:737;23703:5;23751:4;23739:9;23734:3;23730:19;23726:30;23723:50;;;23769:1;23766;23759:12;23723:50;23802:2;23796:9;23844:4;23836:6;23832:17;23915:6;23903:10;23900:22;-1:-1:-1;;;;;23867:10:137;23864:34;23861:62;23858:88;;;23926:18;;:::i;:::-;23966:10;23962:2;23955:22;;23995:6;23986:15;;24031:9;24025:16;24050:39;24081:7;24050:39;:::i;:::-;24098:23;;24166:2;24151:18;;24145:25;24179:33;24145:25;24179:33;:::i;:::-;24245:7;24240:2;24232:6;24228:15;24221:32;;24307:2;24296:9;24292:18;24286:25;24281:2;24273:6;24269:15;24262:50;24366:2;24355:9;24351:18;24345:25;24340:2;24332:6;24328:15;24321:50;;23640:737;;;;:::o;24382:165::-;24460:13;;24513:8;24502:20;;24492:31;;24482:59;;24537:1;24534;24527:12;24552:1104;24655:6;24663;24707:9;24698:7;24694:23;24737:3;24733:2;24729:12;24726:32;;;24754:1;24751;24744:12;24726:32;24783:9;24777:16;24767:26;;24812:6;24852:2;24846;24842:7;24838:2;24834:16;24830:25;24827:45;;;24868:1;24865;24858:12;24827:45;24894:17;;:::i;:::-;24881:30;;24934:49;24979:2;24968:9;24964:18;24934:49;:::i;:::-;24927:5;24920:64;25016:49;25061:2;25050:9;25046:18;25016:49;:::i;:::-;25011:2;25004:5;25000:14;24993:73;25098:48;25142:2;25131:9;25127:18;25098:48;:::i;:::-;25093:2;25086:5;25082:14;25075:72;25179:64;25235:7;25229:3;25218:9;25214:19;25179:64;:::i;:::-;25174:2;25167:5;25163:14;25156:88;25263:3;25299:63;25354:7;25349:2;25338:9;25334:18;25299:63;:::i;:::-;25293:3;25286:5;25282:15;25275:88;25418:3;25407:9;25403:19;25397:26;25390:4;25383:5;25379:16;25372:52;25458:49;25502:3;25491:9;25487:19;25458:49;:::i;:::-;25451:4;25440:16;;25433:75;25562:3;25547:19;;25541:26;25535:3;25524:15;;25517:51;25606:18;;25600:25;25584:14;;;25577:49;;;;-1:-1:-1;24552:1104:137;25444:5;;-1:-1:-1;24552:1104:137:o;26497:210::-;26598:5;26585:19;26613:33;26638:7;26613:33;:::i;:::-;-1:-1:-1;;;;;26667:33:137;26655:46;;;-1:-1:-1;26497:210:137:o;26712:1434::-;27065:25;;;27118:13;;-1:-1:-1;;;;;4770:31:137;27148:2;27133:18;;4758:44;27024:4;27053:3;27199:2;27187:15;;27181:22;-1:-1:-1;;;;;4770:31:137;;27260:2;27245:18;;4758:44;-1:-1:-1;27313:2:137;27301:15;;27295:22;9917:10;9906:22;;27375:2;27360:18;;9894:35;27326:53;27428:2;27420:6;27416:15;27410:22;27441:60;27496:3;27485:9;27481:19;27465:14;27441:60;:::i;:::-;;27550:3;27542:6;27538:16;27532:23;27574:3;27586:59;27641:2;27630:9;27626:18;27610:14;27586:59;:::i;:::-;27700:4;27688:17;;27682:24;27676:3;27661:19;;27654:53;27756:4;27744:17;;27738:24;4889:8;4878:20;27820:3;27805:19;;4866:33;27880:4;27868:17;;27862:24;27856:3;27841:19;;27834:53;27930:15;;27924:22;27918:3;27903:19;;27896:51;-1:-1:-1;27956:66:137;28017:3;28002:19;;27994:6;27956:66;:::i;:::-;28059:2;28053:3;28042:9;28038:19;28031:31;28079:61;28136:2;28125:9;28121:18;28113:6;28105;28079:61;:::i;:::-;28071:69;26712:1434;-1:-1:-1;;;;;;;;26712:1434:137:o;28429:168::-;28469:7;28535:1;28531;28527:6;28523:14;28520:1;28517:21;28512:1;28505:9;28498:17;28494:45;28491:71;;;28542:18;;:::i;:::-;-1:-1:-1;28582:9:137;;28429:168::o;28602:344::-;28796:2;28781:18;;28821:20;;28850:31;28821:20;28850:31;:::i;:::-;-1:-1:-1;;;;;28908:31:137;28890:50;;;28602:344;;-1:-1:-1;28602:344:137:o;29744:289::-;29919:6;29908:9;29901:25;29962:2;29957;29946:9;29942:18;29935:30;29882:4;29982:45;30023:2;30012:9;30008:18;30000:6;29982:45;:::i;30038:287::-;30167:3;30205:6;30199:13;30221:66;30280:6;30275:3;30268:4;30260:6;30256:17;30221:66;:::i;:::-;30303:16;;;;;30038:287;-1:-1:-1;;30038:287:137:o;30330:184::-;30400:6;30453:2;30441:9;30432:7;30428:23;30424:32;30421:52;;;30469:1;30466;30459:12;30421:52;-1:-1:-1;30492:16:137;;30330:184;-1:-1:-1;30330:184:137:o;30948:237::-;31124:3;31109:19;;31137:42;31113:9;31161:6;31137:42;:::i;31190:128::-;31257:9;;;31278:11;;;31275:37;;;31292:18;;:::i;31323:127::-;31384:10;31379:3;31375:20;31372:1;31365:31;31415:4;31412:1;31405:15;31439:4;31436:1;31429:15;31455:217;31495:1;31521;31511:132;;31565:10;31560:3;31556:20;31553:1;31546:31;31600:4;31597:1;31590:15;31628:4;31625:1;31618:15;31511:132;-1:-1:-1;31657:9:137;;31455:217::o;31866:276::-;31935:6;31988:2;31976:9;31967:7;31963:23;31959:32;31956:52;;;32004:1;32001;31994:12;31956:52;32036:9;32030:16;32086:6;32079:5;32075:18;32068:5;32065:29;32055:57;;32108:1;32105;32098:12;33319:273;33387:6;33440:2;33428:9;33419:7;33415:23;33411:32;33408:52;;;33456:1;33453;33446:12;33408:52;33488:9;33482:16;33538:4;33531:5;33527:16;33520:5;33517:27;33507:55;;33558:1;33555;33548:12","linkReferences":{},"immutableReferences":{"63127":[{"start":778,"length":32},{"start":5101,"length":32}],"63130":[{"start":817,"length":32},{"start":5322,"length":32}],"63133":[{"start":557,"length":32},{"start":1534,"length":32},{"start":2713,"length":32},{"start":4235,"length":32},{"start":4829,"length":32},{"start":9364,"length":32},{"start":10350,"length":32},{"start":11349,"length":32}],"63136":[{"start":1107,"length":32},{"start":1865,"length":32},{"start":6772,"length":32},{"start":9974,"length":32},{"start":10153,"length":32},{"start":10488,"length":32},{"start":10924,"length":32},{"start":13278,"length":32}],"63139":[{"start":1205,"length":32},{"start":2434,"length":32},{"start":3266,"length":32},{"start":5658,"length":32}],"63142":[{"start":957,"length":32},{"start":5061,"length":32}]}},"methodIdentifiers":{"ACCRUING_INTEREST_APR_DECIMALS()":"9e8f9540","ACCRUING_INTEREST_APR_DENOMINATOR()":"97b090ea","DOMAIN_SEPARATOR()":"3644e515","EXTENSION_PROPOSAL_TYPEHASH()":"4acacdda","MAX_ACCRUING_INTEREST_APR()":"c399e17d","MAX_EXTENSION_DURATION()":"2c8ebec8","MINUTES_IN_YEAR()":"0eb6f582","MIN_EXTENSION_DURATION()":"7f24133f","MIN_LOAN_DURATION()":"89d99a05","VERSION()":"ffa1ad74","categoryRegistry()":"58099d96","claimLOAN(uint256)":"0ee1ba17","config()":"79502c55","createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)":"764d7713","extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)":"1742123c","extensionProposalsMade(bytes32)":"640d16ed","getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":"74baf6ef","getLOAN(uint256)":"3e6df512","getLenderSpecHash((address))":"c8198080","getStateFingerprint(uint256)":"f5112315","hub()":"365a86fc","isValidAsset((uint8,address,uint256,uint256))":"7122192c","loanMetadataUri()":"111d8a15","loanRepaymentAmount(uint256)":"2c3eae8a","loanToken()":"06d37817","makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":"376af4d1","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","repayLOAN(uint256)":"706048df","revokedNonce()":"9788ad55","supportsInterface(bytes4)":"01ffc9a7","tryClaimRepaidLOAN(uint256,uint256,address)":"94aedc2f"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_hub\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_loanToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_config\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_revokedNonce\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_categoryRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"tag\",\"type\":\"bytes32\"}],\"name\":\"AddressMissingHubTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotLOANTokenHolder\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotVault\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"Expired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncompleteTransfer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InterestAPROutOfBounds\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtensionCaller\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"InvalidExtensionDuration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"allowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"InvalidExtensionSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"current\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"InvalidLenderSpecHash\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"InvalidMultiTokenAsset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"digest\",\"type\":\"bytes32\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"name\":\"InvalidSourceOfFunds\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"timestap\",\"type\":\"uint40\"}],\"name\":\"LoanDefaulted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanNotAutoclaimable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanNotRepaid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanNotRunning\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanRepaid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LoanRunning\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistingLoan\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceNotUsable\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"currentBorrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newBorrower\",\"type\":\"address\"}],\"name\":\"RefinanceBorrowerMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RefinanceCollateralMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RefinanceCreditMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"categoryValue\",\"type\":\"uint8\"}],\"name\":\"UnsupportedCategory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedTransferFunction\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"VaultTransferSameSourceAndDestination\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"extensionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"proposal\",\"type\":\"tuple\"}],\"name\":\"ExtensionProposalMade\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"defaulted\",\"type\":\"bool\"}],\"name\":\"LOANClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposalContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"lender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"duration\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"credit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"bytes32\",\"name\":\"lenderSpecHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"borrowerSpecHash\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoan.Terms\",\"name\":\"terms\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct PWNSimpleLoan.LenderSpec\",\"name\":\"lenderSpec\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extra\",\"type\":\"bytes\"}],\"name\":\"LOANCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"originalDefaultTimestamp\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"extendedDefaultTimestamp\",\"type\":\"uint40\"}],\"name\":\"LOANExtended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"LOANPaidBack\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAdapter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"PoolSupply\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAdapter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"PoolWithdraw\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"}],\"name\":\"VaultPull\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"VaultPush\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"VaultPushFrom\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ACCRUING_INTEREST_APR_DECIMALS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ACCRUING_INTEREST_APR_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"EXTENSION_PROPOSAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_ACCRUING_INTEREST_APR\",\"outputs\":[{\"internalType\":\"uint40\",\"name\":\"\",\"type\":\"uint40\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_EXTENSION_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINUTES_IN_YEAR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_EXTENSION_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_LOAN_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"categoryRegistry\",\"outputs\":[{\"internalType\":\"contract IMultiTokenCategoryRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"claimLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"internalType\":\"contract PWNConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"proposalContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"proposalData\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"proposalInclusionProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PWNSimpleLoan.ProposalSpec\",\"name\":\"proposalSpec\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoan.LenderSpec\",\"name\":\"lenderSpec\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"refinancingLoanId\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"revokeNonce\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.CallerSpec\",\"name\":\"callerSpec\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"extra\",\"type\":\"bytes\"}],\"name\":\"createLOAN\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"extension\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"extendLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"extensionProposalsMade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"extension\",\"type\":\"tuple\"}],\"name\":\"getExtensionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"getLOAN\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint40\",\"name\":\"startTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"defaultTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"originalLender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"loanOwner\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"accruingInterestAPR\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"fixedInterestAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"credit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"originalSourceOfFunds\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repaymentAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceOfFunds\",\"type\":\"address\"}],\"internalType\":\"struct PWNSimpleLoan.LenderSpec\",\"name\":\"lenderSpec\",\"type\":\"tuple\"}],\"name\":\"getLenderSpecHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getStateFingerprint\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hub\",\"outputs\":[{\"internalType\":\"contract PWNHub\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum MultiToken.Category\",\"name\":\"category\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct MultiToken.Asset\",\"name\":\"asset\",\"type\":\"tuple\"}],\"name\":\"isValidAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loanMetadataUri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"loanRepaymentAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loanToken\",\"outputs\":[{\"internalType\":\"contract PWNLOAN\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"compensationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"compensationAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"duration\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"expiration\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonceSpace\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"struct PWNSimpleLoan.ExtensionProposal\",\"name\":\"extension\",\"type\":\"tuple\"}],\"name\":\"makeExtensionProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"}],\"name\":\"repayLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"revokedNonce\",\"outputs\":[{\"internalType\":\"contract PWNRevokedNonce\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loanId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creditAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"loanOwner\",\"type\":\"address\"}],\"name\":\"tryClaimRepaidLOAN\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Acts as a vault for every loan created by this contract.\",\"errors\":{\"InvalidMultiTokenAsset(uint8,address,uint256,uint256)\":[{\"details\":\"Could be because of invalid category, address, id or amount.\"}],\"InvalidSignature(address,bytes32)\":[{\"details\":\"Thrown when signature is invalid.\"}],\"InvalidSignatureLength(uint256)\":[{\"details\":\"Thrown when signature length is not 64 nor 65 bytes.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"details\":\"Maybe nonce is revoked or not in the current nonce space.\"}],\"UnsupportedCategory(uint8)\":[{\"params\":{\"categoryValue\":\"Value of the unsupported category.\"}}]},\"kind\":\"dev\",\"methods\":{\"claimLOAN(uint256)\":{\"details\":\"Only a LOAN token holder can claim a repaid or defaulted loan. Claim will transfer the repaid credit or collateral to a LOAN token holder address and burn the LOAN token.\",\"params\":{\"loanId\":\"Id of a loan that is being claimed.\"}},\"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)\":{\"details\":\"The function assumes a prior token approval to a contract address.\",\"params\":{\"callerSpec\":\"Caller specification struct.\",\"extra\":\"Auxiliary data that are emitted in the loan creation event. They are not used in the contract logic.\",\"lenderSpec\":\"Lender specification struct.\",\"proposalSpec\":\"Proposal specification struct.\"},\"returns\":{\"loanId\":\"Id of the created LOAN token.\"}},\"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)\":{\"details\":\"The function assumes a prior token approval to a contract address.\",\"params\":{\"extension\":\"Extension proposal struct.\",\"signature\":\"Signature of the extension proposal.\"}},\"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"params\":{\"extension\":\"Extension proposal struct.\"},\"returns\":{\"_0\":\"Hash of the extension struct.\"}},\"getLOAN(uint256)\":{\"params\":{\"loanId\":\"Id of a loan in question.\"},\"returns\":{\"accruingInterestAPR\":\"Accruing interest APR with 2 decimal places.\",\"borrower\":\"Address of a loan borrower.\",\"collateral\":\"Asset used as a loan collateral. For a definition see { MultiToken dependency lib }.\",\"credit\":\"Asset used as a loan credit. For a definition see { MultiToken dependency lib }.\",\"defaultTimestamp\":\"Unix timestamp (in seconds) of a loan default date.\",\"fixedInterestAmount\":\"Fixed interest amount in credit asset tokens.\",\"loanOwner\":\"Address of a LOAN token holder.\",\"originalLender\":\"Address of a loan original lender.\",\"originalSourceOfFunds\":\"Address of a source of funds for the loan. Original lender address, if the loan was funded directly, or a pool address from witch credit funds were withdrawn / borrowred.\",\"repaymentAmount\":\"Loan repayment amount in credit asset tokens.\",\"startTimestamp\":\"Unix timestamp (in seconds) of a loan creation date.\",\"status\":\"LOAN status.\"}},\"getLenderSpecHash((address))\":{\"params\":{\"lenderSpec\":\"Lender specification struct.\"},\"returns\":{\"_0\":\"Hash of a lender specification.\"}},\"getStateFingerprint(uint256)\":{\"params\":{\"tokenId\":\"Id of a token state in question.\"},\"returns\":{\"_0\":\"Current token state fingerprint.\"}},\"isValidAsset((uint8,address,uint256,uint256))\":{\"details\":\"See MultiToken.isValid for more details.\",\"params\":{\"asset\":\"Asset to be checked.\"},\"returns\":{\"_0\":\"True if the asset is valid.\"}},\"loanMetadataUri()\":{\"returns\":{\"_0\":\"LOAN token metadata uri.\"}},\"loanRepaymentAmount(uint256)\":{\"params\":{\"loanId\":\"Id of a loan.\"},\"returns\":{\"_0\":\"Repayment amount.\"}},\"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"params\":{\"extension\":\"Extension proposal struct.\"}},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` (i.e. 0xbc197c81, or its own function selector).\",\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\"}},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` (i.e. 0xf23a6e61, or its own function selector).\",\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\"}},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\",\"returns\":{\"_0\":\"`IERC721Receiver.onERC721Received.selector` if transfer is allowed\"}},\"repayLOAN(uint256)\":{\"details\":\"Any address can repay a running loan, but a collateral will be transferred to a borrower address associated with the loan. If the LOAN token holder is the same as the original lender, the repayment credit asset will be transferred to the LOAN token holder directly. Otherwise it will transfer the repayment credit asset to a vault, waiting on a LOAN token holder to claim it. The function assumes a prior token approval to a contract address.\",\"params\":{\"loanId\":\"Id of a loan that is being repaid.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"tryClaimRepaidLOAN(uint256,uint256,address)\":{\"details\":\"The function is called by the vault to repay a loan directly to the original lender or its source of funds if the loan owner is the original lender. If the transfer fails, the LOAN token will remain in repaid state and the LOAN token owner will be able to claim the repaid credit. Otherwise lender would be able to prevent borrower from repaying the loan.\",\"params\":{\"creditAmount\":\"Amount of a credit to be claimed.\",\"loanId\":\"Id of a loan that is being claimed.\",\"loanOwner\":\"Address of the LOAN token holder.\"}}},\"title\":\"PWN Simple Loan\",\"version\":1},\"userdoc\":{\"errors\":{\"AddressMissingHubTag(address,bytes32)\":[{\"notice\":\"Thrown when an address is missing a PWN Hub tag.\"}],\"CallerNotLOANTokenHolder()\":[{\"notice\":\"Thrown when caller is not a LOAN token holder.\"}],\"CallerNotVault()\":[{\"notice\":\"Thrown when caller is not a vault.\"}],\"Expired(uint256,uint256)\":[{\"notice\":\"Thrown when a proposal is expired.\"}],\"IncompleteTransfer()\":[{\"notice\":\"Thrown when an asset transfer is incomplete.\"}],\"InterestAPROutOfBounds(uint256,uint256)\":[{\"notice\":\"Thrown when accruing interest APR is above the maximum.\"}],\"InvalidDuration(uint256,uint256)\":[{\"notice\":\"Thrown when loan duration is below the minimum.\"}],\"InvalidExtensionCaller()\":[{\"notice\":\"Thrown when caller is not a loan borrower or lender.\"}],\"InvalidExtensionDuration(uint256,uint256)\":[{\"notice\":\"Thrown when loan extension duration is out of bounds.\"}],\"InvalidExtensionSigner(address,address)\":[{\"notice\":\"Thrown when signer is not a loan extension proposer.\"}],\"InvalidLenderSpecHash(bytes32,bytes32)\":[{\"notice\":\"Thrown when hash of provided lender spec doesn't match the one in loan terms.\"}],\"InvalidMultiTokenAsset(uint8,address,uint256,uint256)\":[{\"notice\":\"Thrown when MultiToken.Asset is invalid.\"}],\"InvalidSourceOfFunds(address)\":[{\"notice\":\"Thrown when pool based source of funds doesn't have a registered adapter.\"}],\"LoanDefaulted(uint40)\":[{\"notice\":\"Thrown when managed loan is defaulted.\"}],\"LoanNotAutoclaimable()\":[{\"notice\":\"Thrown when loan cannot be claimed on repayment.\"}],\"LoanNotRepaid()\":[{\"notice\":\"Thrown when managed loan is not repaid.\"}],\"LoanNotRunning()\":[{\"notice\":\"Thrown when managed loan is running.\"}],\"LoanRepaid()\":[{\"notice\":\"Thrown when managed loan is repaid.\"}],\"LoanRunning()\":[{\"notice\":\"Thrown when manged loan is still running.\"}],\"NonExistingLoan()\":[{\"notice\":\"Thrown when loan doesn't exist.\"}],\"NonceNotUsable(address,uint256,uint256)\":[{\"notice\":\"Thrown when nonce is currently not usable.\"}],\"RefinanceBorrowerMismatch(address,address)\":[{\"notice\":\"Thrown when refinancing loan terms have different borrower than the original loan.\"}],\"RefinanceCollateralMismatch()\":[{\"notice\":\"Thrown when refinancing loan terms have different collateral asset than the original loan.\"}],\"RefinanceCreditMismatch()\":[{\"notice\":\"Thrown when refinancing loan terms have different credit asset than the original loan.\"}],\"UnsupportedCategory(uint8)\":[{\"notice\":\"Thrown when unsupported category is used.\"}],\"UnsupportedTransferFunction()\":[{\"notice\":\"Thrown when the Vault receives an asset that is not transferred by the Vault itself.\"}],\"VaultTransferSameSourceAndDestination(address)\":[{\"notice\":\"Thrown when an asset transfer source and destination address are the same.\"}]},\"events\":{\"ExtensionProposalMade(bytes32,address,(uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"notice\":\"Emitted when a loan extension proposal is made.\"},\"LOANClaimed(uint256,bool)\":{\"notice\":\"Emitted when a repaid or defaulted loan is claimed.\"},\"LOANCreated(uint256,bytes32,address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes)\":{\"notice\":\"Emitted when a new loan in created.\"},\"LOANExtended(uint256,uint40,uint40)\":{\"notice\":\"Emitted when a LOAN token holder extends a loan.\"},\"LOANPaidBack(uint256)\":{\"notice\":\"Emitted when a loan is paid back.\"},\"PoolSupply((uint8,address,uint256,uint256),address,address,address)\":{\"notice\":\"Emitted when asset is supplied to a pool from a vault.\"},\"PoolWithdraw((uint8,address,uint256,uint256),address,address,address)\":{\"notice\":\"Emitted when asset is withdrawn from a pool to an `owner` address.\"},\"VaultPull((uint8,address,uint256,uint256),address)\":{\"notice\":\"Emitted when asset transfer happens from an `origin` address to a vault.\"},\"VaultPush((uint8,address,uint256,uint256),address)\":{\"notice\":\"Emitted when asset transfer happens from a vault to a `beneficiary` address.\"},\"VaultPushFrom((uint8,address,uint256,uint256),address,address)\":{\"notice\":\"Emitted when asset transfer happens from an `origin` address to a `beneficiary` address.\"}},\"kind\":\"user\",\"methods\":{\"claimLOAN(uint256)\":{\"notice\":\"Claim a repaid or defaulted loan.\"},\"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)\":{\"notice\":\"Create a new loan.\"},\"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)\":{\"notice\":\"Extend loans default date with signed extension proposal signed by borrower or LOAN token owner.\"},\"extensionProposalsMade(bytes32)\":{\"notice\":\"Mapping of extension proposals made via on-chain transaction by extension hash.\"},\"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"notice\":\"Get the hash of the extension struct.\"},\"getLOAN(uint256)\":{\"notice\":\"Return a LOAN data struct associated with a loan id.\"},\"getLenderSpecHash((address))\":{\"notice\":\"Get hash of a lender specification.\"},\"getStateFingerprint(uint256)\":{\"notice\":\"Function to return current token state fingerprint.\"},\"isValidAsset((uint8,address,uint256,uint256))\":{\"notice\":\"Check if the asset is valid with the MultiToken dependency lib and the category registry.\"},\"loanMetadataUri()\":{\"notice\":\"Get a loan metadata uri for a LOAN token minted by this contract.\"},\"loanRepaymentAmount(uint256)\":{\"notice\":\"Calculate the loan repayment amount with fixed and accrued interest.\"},\"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))\":{\"notice\":\"Make an on-chain extension proposal.\"},\"repayLOAN(uint256)\":{\"notice\":\"Repay running loan.\"},\"tryClaimRepaidLOAN(uint256,uint256,address)\":{\"notice\":\"Try to claim a repaid loan for the loan owner.\"}},\"notice\":\"Contract managing a simple loan in PWN protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/loan/terms/simple/loan/PWNSimpleLoan.sol\":\"PWNSimpleLoan\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":MultiToken/=lib/MultiToken/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":multitoken/=lib/MultiToken/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":openzeppelin/=lib/openzeppelin-contracts/contracts/\",\":pwn/=src/\"]},\"sources\":{\"lib/MultiToken/src/MultiToken.sol\":{\"keccak256\":\"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18\",\"dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh\"]},\"lib/MultiToken/src/interfaces/ICryptoKitties.sol\":{\"keccak256\":\"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa\",\"dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze\"]},\"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol\":{\"keccak256\":\"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1\",\"dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\":{\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16\",\"dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c\",\"dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e\",\"dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b\",\"dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95\",\"dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32\",\"dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e\",\"dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol\":{\"keccak256\":\"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b\",\"dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45\",\"dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol\":{\"keccak256\":\"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8\",\"dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6\"]},\"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol\":{\"keccak256\":\"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf\",\"dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf\"]},\"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec\",\"dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005\",\"dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4\",\"dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c\",\"dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol\":{\"keccak256\":\"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04\",\"dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd\",\"dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278\",\"dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"src/PWNErrors.sol\":{\"keccak256\":\"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f\",\"dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc\"]},\"src/config/PWNConfig.sol\":{\"keccak256\":\"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7\",\"dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz\"]},\"src/hub/PWNHub.sol\":{\"keccak256\":\"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b\",\"dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET\"]},\"src/hub/PWNHubTags.sol\":{\"keccak256\":\"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8\",\"dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ\"]},\"src/interfaces/IERC5646.sol\":{\"keccak256\":\"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180\",\"dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki\"]},\"src/interfaces/IPWNLoanMetadataProvider.sol\":{\"keccak256\":\"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6\",\"dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK\"]},\"src/interfaces/IPoolAdapter.sol\":{\"keccak256\":\"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b\",\"dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T\"]},\"src/interfaces/IStateFingerpringComputer.sol\":{\"keccak256\":\"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c\",\"dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct\"]},\"src/loan/lib/PWNFeeCalculator.sol\":{\"keccak256\":\"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5\",\"dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq\"]},\"src/loan/lib/PWNSignatureChecker.sol\":{\"keccak256\":\"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1\",\"dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM\"]},\"src/loan/terms/simple/loan/PWNSimpleLoan.sol\":{\"keccak256\":\"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129\",\"dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP\"]},\"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol\":{\"keccak256\":\"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13\",\"dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP\"]},\"src/loan/token/PWNLOAN.sol\":{\"keccak256\":\"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219\",\"dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo\"]},\"src/loan/vault/PWNVault.sol\":{\"keccak256\":\"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b\",\"dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq\"]},\"src/nonce/PWNRevokedNonce.sol\":{\"keccak256\":\"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f\",\"dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS\"]},\"src/utilized-credit/PWNUtilizedCredit.sol\":{\"keccak256\":\"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441\",\"dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.16+commit.07a7930e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"address","name":"_loanToken","type":"address"},{"internalType":"address","name":"_config","type":"address"},{"internalType":"address","name":"_revokedNonce","type":"address"},{"internalType":"address","name":"_categoryRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"tag","type":"bytes32"}],"type":"error","name":"AddressMissingHubTag"},{"inputs":[],"type":"error","name":"CallerNotLOANTokenHolder"},{"inputs":[],"type":"error","name":"CallerNotVault"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"type":"error","name":"Expired"},{"inputs":[],"type":"error","name":"IncompleteTransfer"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InterestAPROutOfBounds"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InvalidDuration"},{"inputs":[],"type":"error","name":"InvalidExtensionCaller"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"type":"error","name":"InvalidExtensionDuration"},{"inputs":[{"internalType":"address","name":"allowed","type":"address"},{"internalType":"address","name":"current","type":"address"}],"type":"error","name":"InvalidExtensionSigner"},{"inputs":[{"internalType":"bytes32","name":"current","type":"bytes32"},{"internalType":"bytes32","name":"expected","type":"bytes32"}],"type":"error","name":"InvalidLenderSpecHash"},{"inputs":[{"internalType":"uint8","name":"category","type":"uint8"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"type":"error","name":"InvalidMultiTokenAsset"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"digest","type":"bytes32"}],"type":"error","name":"InvalidSignature"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"type":"error","name":"InvalidSignatureLength"},{"inputs":[{"internalType":"address","name":"sourceOfFunds","type":"address"}],"type":"error","name":"InvalidSourceOfFunds"},{"inputs":[{"internalType":"uint40","name":"timestap","type":"uint40"}],"type":"error","name":"LoanDefaulted"},{"inputs":[],"type":"error","name":"LoanNotAutoclaimable"},{"inputs":[],"type":"error","name":"LoanNotRepaid"},{"inputs":[],"type":"error","name":"LoanNotRunning"},{"inputs":[],"type":"error","name":"LoanRepaid"},{"inputs":[],"type":"error","name":"LoanRunning"},{"inputs":[],"type":"error","name":"NonExistingLoan"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"type":"error","name":"NonceNotUsable"},{"inputs":[{"internalType":"address","name":"currentBorrower","type":"address"},{"internalType":"address","name":"newBorrower","type":"address"}],"type":"error","name":"RefinanceBorrowerMismatch"},{"inputs":[],"type":"error","name":"RefinanceCollateralMismatch"},{"inputs":[],"type":"error","name":"RefinanceCreditMismatch"},{"inputs":[{"internalType":"uint8","name":"categoryValue","type":"uint8"}],"type":"error","name":"UnsupportedCategory"},{"inputs":[],"type":"error","name":"UnsupportedTransferFunction"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"type":"error","name":"VaultTransferSameSourceAndDestination"},{"inputs":[{"internalType":"bytes32","name":"extensionHash","type":"bytes32","indexed":true},{"internalType":"address","name":"proposer","type":"address","indexed":true},{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"proposal","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"indexed":false}],"type":"event","name":"ExtensionProposalMade","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"bool","name":"defaulted","type":"bool","indexed":true}],"type":"event","name":"LOANClaimed","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"bytes32","name":"proposalHash","type":"bytes32","indexed":true},{"internalType":"address","name":"proposalContract","type":"address","indexed":true},{"internalType":"uint256","name":"refinancingLoanId","type":"uint256","indexed":false},{"internalType":"struct PWNSimpleLoan.Terms","name":"terms","type":"tuple","components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint32","name":"duration","type":"uint32"},{"internalType":"struct MultiToken.Asset","name":"collateral","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"struct MultiToken.Asset","name":"credit","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"bytes32","name":"lenderSpecHash","type":"bytes32"},{"internalType":"bytes32","name":"borrowerSpecHash","type":"bytes32"}],"indexed":false},{"internalType":"struct PWNSimpleLoan.LenderSpec","name":"lenderSpec","type":"tuple","components":[{"internalType":"address","name":"sourceOfFunds","type":"address"}],"indexed":false},{"internalType":"bytes","name":"extra","type":"bytes","indexed":false}],"type":"event","name":"LOANCreated","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true},{"internalType":"uint40","name":"originalDefaultTimestamp","type":"uint40","indexed":false},{"internalType":"uint40","name":"extendedDefaultTimestamp","type":"uint40","indexed":false}],"type":"event","name":"LOANExtended","anonymous":false},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256","indexed":true}],"type":"event","name":"LOANPaidBack","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"poolAdapter","type":"address","indexed":true},{"internalType":"address","name":"pool","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true}],"type":"event","name":"PoolSupply","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"poolAdapter","type":"address","indexed":true},{"internalType":"address","name":"pool","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true}],"type":"event","name":"PoolWithdraw","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"origin","type":"address","indexed":true}],"type":"event","name":"VaultPull","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"beneficiary","type":"address","indexed":true}],"type":"event","name":"VaultPush","anonymous":false},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false},{"internalType":"address","name":"origin","type":"address","indexed":true},{"internalType":"address","name":"beneficiary","type":"address","indexed":true}],"type":"event","name":"VaultPushFrom","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"ACCRUING_INTEREST_APR_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"ACCRUING_INTEREST_APR_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"EXTENSION_PROPOSAL_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MAX_ACCRUING_INTEREST_APR","outputs":[{"internalType":"uint40","name":"","type":"uint40"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MAX_EXTENSION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MINUTES_IN_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MIN_EXTENSION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"MIN_LOAN_DURATION","outputs":[{"internalType":"uint32","name":"","type":"uint32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"categoryRegistry","outputs":[{"internalType":"contract IMultiTokenCategoryRegistry","name":"","type":"address"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"claimLOAN"},{"inputs":[],"stateMutability":"view","type":"function","name":"config","outputs":[{"internalType":"contract PWNConfig","name":"","type":"address"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ProposalSpec","name":"proposalSpec","type":"tuple","components":[{"internalType":"address","name":"proposalContract","type":"address"},{"internalType":"bytes","name":"proposalData","type":"bytes"},{"internalType":"bytes32[]","name":"proposalInclusionProof","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]},{"internalType":"struct PWNSimpleLoan.LenderSpec","name":"lenderSpec","type":"tuple","components":[{"internalType":"address","name":"sourceOfFunds","type":"address"}]},{"internalType":"struct PWNSimpleLoan.CallerSpec","name":"callerSpec","type":"tuple","components":[{"internalType":"uint256","name":"refinancingLoanId","type":"uint256"},{"internalType":"bool","name":"revokeNonce","type":"bool"},{"internalType":"uint256","name":"nonce","type":"uint256"}]},{"internalType":"bytes","name":"extra","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"createLOAN","outputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"extension","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}]},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"extendLOAN"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","name":"extensionProposalsMade","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"extension","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}]}],"stateMutability":"view","type":"function","name":"getExtensionHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getLOAN","outputs":[{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint40","name":"startTimestamp","type":"uint40"},{"internalType":"uint40","name":"defaultTimestamp","type":"uint40"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"originalLender","type":"address"},{"internalType":"address","name":"loanOwner","type":"address"},{"internalType":"uint24","name":"accruingInterestAPR","type":"uint24"},{"internalType":"uint256","name":"fixedInterestAmount","type":"uint256"},{"internalType":"struct MultiToken.Asset","name":"credit","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"struct MultiToken.Asset","name":"collateral","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"address","name":"originalSourceOfFunds","type":"address"},{"internalType":"uint256","name":"repaymentAmount","type":"uint256"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.LenderSpec","name":"lenderSpec","type":"tuple","components":[{"internalType":"address","name":"sourceOfFunds","type":"address"}]}],"stateMutability":"pure","type":"function","name":"getLenderSpecHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getStateFingerprint","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"hub","outputs":[{"internalType":"contract PWNHub","name":"","type":"address"}]},{"inputs":[{"internalType":"struct MultiToken.Asset","name":"asset","type":"tuple","components":[{"internalType":"enum MultiToken.Category","name":"category","type":"uint8"},{"internalType":"address","name":"assetAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}]}],"stateMutability":"view","type":"function","name":"isValidAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"loanMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"view","type":"function","name":"loanRepaymentAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"loanToken","outputs":[{"internalType":"contract PWNLOAN","name":"","type":"address"}]},{"inputs":[{"internalType":"struct PWNSimpleLoan.ExtensionProposal","name":"extension","type":"tuple","components":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"address","name":"compensationAddress","type":"address"},{"internalType":"uint256","name":"compensationAmount","type":"uint256"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"nonceSpace","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}]}],"stateMutability":"nonpayable","type":"function","name":"makeExtensionProposal"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function","name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}]},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function","name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}]},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function","name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"repayLOAN"},{"inputs":[],"stateMutability":"view","type":"function","name":"revokedNonce","outputs":[{"internalType":"contract PWNRevokedNonce","name":"","type":"address"}]},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"pure","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"uint256","name":"loanId","type":"uint256"},{"internalType":"uint256","name":"creditAmount","type":"uint256"},{"internalType":"address","name":"loanOwner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"tryClaimRepaidLOAN"}],"devdoc":{"kind":"dev","methods":{"claimLOAN(uint256)":{"details":"Only a LOAN token holder can claim a repaid or defaulted loan. Claim will transfer the repaid credit or collateral to a LOAN token holder address and burn the LOAN token.","params":{"loanId":"Id of a loan that is being claimed."}},"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)":{"details":"The function assumes a prior token approval to a contract address.","params":{"callerSpec":"Caller specification struct.","extra":"Auxiliary data that are emitted in the loan creation event. They are not used in the contract logic.","lenderSpec":"Lender specification struct.","proposalSpec":"Proposal specification struct."},"returns":{"loanId":"Id of the created LOAN token."}},"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)":{"details":"The function assumes a prior token approval to a contract address.","params":{"extension":"Extension proposal struct.","signature":"Signature of the extension proposal."}},"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"params":{"extension":"Extension proposal struct."},"returns":{"_0":"Hash of the extension struct."}},"getLOAN(uint256)":{"params":{"loanId":"Id of a loan in question."},"returns":{"accruingInterestAPR":"Accruing interest APR with 2 decimal places.","borrower":"Address of a loan borrower.","collateral":"Asset used as a loan collateral. For a definition see { MultiToken dependency lib }.","credit":"Asset used as a loan credit. For a definition see { MultiToken dependency lib }.","defaultTimestamp":"Unix timestamp (in seconds) of a loan default date.","fixedInterestAmount":"Fixed interest amount in credit asset tokens.","loanOwner":"Address of a LOAN token holder.","originalLender":"Address of a loan original lender.","originalSourceOfFunds":"Address of a source of funds for the loan. Original lender address, if the loan was funded directly, or a pool address from witch credit funds were withdrawn / borrowred.","repaymentAmount":"Loan repayment amount in credit asset tokens.","startTimestamp":"Unix timestamp (in seconds) of a loan creation date.","status":"LOAN status."}},"getLenderSpecHash((address))":{"params":{"lenderSpec":"Lender specification struct."},"returns":{"_0":"Hash of a lender specification."}},"getStateFingerprint(uint256)":{"params":{"tokenId":"Id of a token state in question."},"returns":{"_0":"Current token state fingerprint."}},"isValidAsset((uint8,address,uint256,uint256))":{"details":"See MultiToken.isValid for more details.","params":{"asset":"Asset to be checked."},"returns":{"_0":"True if the asset is valid."}},"loanMetadataUri()":{"returns":{"_0":"LOAN token metadata uri."}},"loanRepaymentAmount(uint256)":{"params":{"loanId":"Id of a loan."},"returns":{"_0":"Repayment amount."}},"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"params":{"extension":"Extension proposal struct."}},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81, or its own function selector).","returns":{"_0":"`bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed"}},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61, or its own function selector).","returns":{"_0":"`bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed"}},"onERC721Received(address,address,uint256,bytes)":{"details":"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.","returns":{"_0":"`IERC721Receiver.onERC721Received.selector` if transfer is allowed"}},"repayLOAN(uint256)":{"details":"Any address can repay a running loan, but a collateral will be transferred to a borrower address associated with the loan. If the LOAN token holder is the same as the original lender, the repayment credit asset will be transferred to the LOAN token holder directly. Otherwise it will transfer the repayment credit asset to a vault, waiting on a LOAN token holder to claim it. The function assumes a prior token approval to a contract address.","params":{"loanId":"Id of a loan that is being repaid."}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"tryClaimRepaidLOAN(uint256,uint256,address)":{"details":"The function is called by the vault to repay a loan directly to the original lender or its source of funds if the loan owner is the original lender. If the transfer fails, the LOAN token will remain in repaid state and the LOAN token owner will be able to claim the repaid credit. Otherwise lender would be able to prevent borrower from repaying the loan.","params":{"creditAmount":"Amount of a credit to be claimed.","loanId":"Id of a loan that is being claimed.","loanOwner":"Address of the LOAN token holder."}}},"version":1},"userdoc":{"kind":"user","methods":{"claimLOAN(uint256)":{"notice":"Claim a repaid or defaulted loan."},"createLOAN((address,bytes,bytes32[],bytes),(address),(uint256,bool,uint256),bytes)":{"notice":"Create a new loan."},"extendLOAN((uint256,address,uint256,uint40,uint40,address,uint256,uint256),bytes)":{"notice":"Extend loans default date with signed extension proposal signed by borrower or LOAN token owner."},"extensionProposalsMade(bytes32)":{"notice":"Mapping of extension proposals made via on-chain transaction by extension hash."},"getExtensionHash((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"notice":"Get the hash of the extension struct."},"getLOAN(uint256)":{"notice":"Return a LOAN data struct associated with a loan id."},"getLenderSpecHash((address))":{"notice":"Get hash of a lender specification."},"getStateFingerprint(uint256)":{"notice":"Function to return current token state fingerprint."},"isValidAsset((uint8,address,uint256,uint256))":{"notice":"Check if the asset is valid with the MultiToken dependency lib and the category registry."},"loanMetadataUri()":{"notice":"Get a loan metadata uri for a LOAN token minted by this contract."},"loanRepaymentAmount(uint256)":{"notice":"Calculate the loan repayment amount with fixed and accrued interest."},"makeExtensionProposal((uint256,address,uint256,uint40,uint40,address,uint256,uint256))":{"notice":"Make an on-chain extension proposal."},"repayLOAN(uint256)":{"notice":"Repay running loan."},"tryClaimRepaidLOAN(uint256,uint256,address)":{"notice":"Try to claim a repaid loan for the loan owner."}},"version":1}},"settings":{"remappings":["MultiToken/=lib/MultiToken/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","multitoken/=lib/MultiToken/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","pwn/=src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/loan/terms/simple/loan/PWNSimpleLoan.sol":"PWNSimpleLoan"},"evmVersion":"london","libraries":{}},"sources":{"lib/MultiToken/src/MultiToken.sol":{"keccak256":"0xf53dbbf41b9e3dd8263f70064cfc68a6f2ff2fcfb3822394d39970bcb2f934da","urls":["bzz-raw://1cfebf43093782d79b47a14f918e133dbb8044749aa956c82e68ac6a2dfcbb18","dweb:/ipfs/QmRTxX2VDWeHmcF8qHRLtzGhCTNd8sc4JCJoUfLvHAjkMh"],"license":"MIT"},"lib/MultiToken/src/interfaces/ICryptoKitties.sol":{"keccak256":"0x9aaa7f948d4f2121d764b5664fe1c8431b3c5bfce780228eceb56d1589681706","urls":["bzz-raw://05416e111c8ff6a1464248ac387e8c69015c355e949967586d514d9d17d619aa","dweb:/ipfs/QmVK5Q6bS1CevgdxB17RJ9BGZsspCXdY5Y5dX4cpgQ4Rze"],"license":"MIT"},"lib/MultiToken/src/interfaces/IMultiTokenCategoryRegistry.sol":{"keccak256":"0x5607c7415785a07c7226638ab7d16ae9a87906e5eafb06e723944144b8f7c48a","urls":["bzz-raw://dd5f1d39f2acb6cda18a1199e06be211deccce27478de077d942ced8ada6e0b1","dweb:/ipfs/Qmdx2uXjyoyyqNQU5aQTpagujxSVAfS17Sc3ziJGAofXnX"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol":{"keccak256":"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510","urls":["bzz-raw://75267b14b60dc216d01d596a4008189a6c44d3314e53eded0edb1e757d95be16","dweb:/ipfs/QmQoMaxTRT6V7uQj9USfdQH9jh1crywB9auVjThzUSAbG2"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"keccak256":"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e","urls":["bzz-raw://e89863421b4014b96a4b62be76eb3b9f0a8afe9684664a6f389124c0964bfe5c","dweb:/ipfs/Qmbk7xr1irpDuU1WdxXgxELBXxs61rHhCgod7heVcvFx16"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794","urls":["bzz-raw://f103ee2e4aecd37aac6ceefe670709cdd7613dee25fa2d4d9feaf7fc0aaa155e","dweb:/ipfs/QmRiNZLoJk5k3HPMYGPGjZFd2ke1ZxjhJZkM45Ec9GH9hv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"keccak256":"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422","urls":["bzz-raw://310136ad60820af4177a11a61d77a3686faf5fca4942b600e08fc940db38396b","dweb:/ipfs/QmbCzMNSTL7Zi7M4UCSqBrkHtp4jjxUnGbkneCZKdR1qeq"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef","urls":["bzz-raw://8b06267c5f80bad727af3e48b1382333d591dad51376399ef2f6b0ee6d58bf95","dweb:/ipfs/QmdU5La1agcQvghnfMpWZGDPz2TUDTCxUwTLKmuMRXBpAx"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218","urls":["bzz-raw://fc980984badf3984b6303b377711220e067722bbd6a135b24669ff5069ef9f32","dweb:/ipfs/QmPHXMSXj99XjSVM21YsY6aNtLLjLVXDbyN76J5HQYvvrz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c","urls":["bzz-raw://1fd55624076bf61d44af5ff351919e32dda748567acfbdd6ba3d6c7be61c758e","dweb:/ipfs/QmSki4dTrf4GPm7MTpG3fk8mC7rnjwd2zMomLp6jLuF63Q"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol":{"keccak256":"0x10a6688bc4154b1b76268dbaf497bd8b24f77525ecb9cf829bd3cccec98eefc2","urls":["bzz-raw://68663f939b79e88a5bb677cf6c549e88eb4f587379c09f80d19cde14b0eb984b","dweb:/ipfs/QmVfeL1uxQ5161d25DsNqptjaur7VQugjCSGitrRscTdmV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45","urls":["bzz-raw://2900536cdadec954ced8789a9d1ed4b5e640029e1424e91fd5b88026486f4d45","dweb:/ipfs/QmUMUX7CuYoiHvFkhifqtXGaciw2wnm4t9sAoPzETZ3Gbq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol":{"keccak256":"0xaf297d12d8d4a57fe01a70f0ef38908f208e3faedc577056d0b728fa2f3ccf0c","urls":["bzz-raw://fbfaf37123958822a2720a4ea29651be00edab787540b770f73d3e025d286ff8","dweb:/ipfs/QmbzgWeTm8hJVUqWrNAwFjshqbYVyeGpQA8D1huzxQdmw6"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol":{"keccak256":"0xcab667ddad478ff0d39c2053ca77fac778af8483c18ab07d810277b4216fd582","urls":["bzz-raw://919c7ea27c77275c3c341da0c4a26a66a20ed27605fbe8becf11f58ec3bc65bf","dweb:/ipfs/QmRLKyVE2n7e2Jo4bLNn8eLgqqhNGYnVQyjJPWdr8poskf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol":{"keccak256":"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b","urls":["bzz-raw://0e28648f994abf1d6bc345644a361cc0b7efa544f8bc0c8ec26011fed85a91ec","dweb:/ipfs/QmVVE7AiRjKaQYYji7TkjmTeVzGpNmms5eoxqTCfvvpj6D"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439","urls":["bzz-raw://a367861093b74443b137564d3f3c472f70bcf114739e62059c939f25e315706c","dweb:/ipfs/Qmd7JMpcxD9RuQjK3uM3EzJUgSqdN8vzp8eytEiuwxQJ6h"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol":{"keccak256":"0xcf688741f79f4838d5301dcf72d0af9eff11bbab6ab0bb112ad144c7fb672dac","urls":["bzz-raw://85d9c87a481fe99fd28a146c205da0867ef7e1b7edbe0036abc86d2e64eb1f04","dweb:/ipfs/QmR7m1zWQNfZHUKTtqnjoCjCBbNFcjCxV27rxf6iMfhVtG"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol":{"keccak256":"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5","urls":["bzz-raw://6f7bb74cf88fd88daa34e118bc6e363381d05044f34f391d39a10c0c9dac3ebd","dweb:/ipfs/QmNbQ3v8v4zuDtg7VeLAbdhAm3tCzUodNoDZZ8ekmCHWZX"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad","urls":["bzz-raw://495145362c7ff1c9ca88c58bbbbcb412e3c2004406647412394486552ff6c278","dweb:/ipfs/QmNNCeng6d5eRPDn6tkWSQhjE39XWfQEfjA63rRwHmr1iH"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"src/PWNErrors.sol":{"keccak256":"0xe38409d979b2b79570ed62eae094f047f1795f00f104b133cd115820dfb8eb24","urls":["bzz-raw://53801fc8df9942bd966648f83c531437f618c5d6c896afaad060fe75b024996f","dweb:/ipfs/QmeP9N2BGkfz5a7fqYaeFy2dKX56TbAyiXt3RZcshQhsUc"],"license":"GPL-3.0-only"},"src/config/PWNConfig.sol":{"keccak256":"0xedbf83535c04ce20d580826437da4b48623d959df416d938788fb98da883d44f","urls":["bzz-raw://d629477855dc23ac474ccff936a55432003e68c63165b4889599b80a59eaeca7","dweb:/ipfs/QmZze4BwYtDPHpYYHHarD59sx2HFKE8T7uYebgCSDPbTfz"],"license":"GPL-3.0-only"},"src/hub/PWNHub.sol":{"keccak256":"0xdc16cd5a97ec99de02185cc4055063784b629ed2e410955e3f4ec89f1fa0b492","urls":["bzz-raw://3ce598f78a13773b779b94b1cc10a336d06d66a37113d4d2058c3b8d51d0825b","dweb:/ipfs/QmWF8gkbzwXEFd7MxjgV66XEAtL38TVZeysrhUjDPjs3ET"],"license":"GPL-3.0-only"},"src/hub/PWNHubTags.sol":{"keccak256":"0xd1e685e8075f1f16835d38cfe39b1eee9edbf75089a0109002f7b2bfe14c177a","urls":["bzz-raw://4a01df6b1c2cf493017b7abb4b9ec6ac16c9b1c3498b16ccbdc4f2045909dde8","dweb:/ipfs/QmcYEgSZrE33YKxDDBvhVgZTfT9Tj1RTEX3iA717zZyspJ"],"license":"GPL-3.0-only"},"src/interfaces/IERC5646.sol":{"keccak256":"0xff5ce494375d2cf5a67fe9460ea66aa3572b8a0434ae538cbac0a55f7aac5c5e","urls":["bzz-raw://e8e2b472fa80a92ae12985da77056f68f0e0f36fca7ac37b6d30db82a2527180","dweb:/ipfs/QmdFTGSCaPcVfthbGSUuiyhivqBx6xN9dCL14PCbR39Wki"],"license":"GPL-3.0-only"},"src/interfaces/IPWNLoanMetadataProvider.sol":{"keccak256":"0x6cc991fd9c8c88e0a69e835fcd514868836e2432b12454dfcb6a681a3a9d13b8","urls":["bzz-raw://69fd07433fd7eb2f1474d778476240434fa79a31525341d88a588573562389c6","dweb:/ipfs/Qmb6gWNQD96oSgwH5Yf6eMHxYWXZwCPrd7MvK86r7UKhZK"],"license":"GPL-3.0-only"},"src/interfaces/IPoolAdapter.sol":{"keccak256":"0xe0309b4e7da2046095c7dc943d953f32d2a46b0ad64beaf3f4ed1b440fe43f89","urls":["bzz-raw://15870bf95e096b35620787a0eba49f7becbaff738651a83bd28310d022cdc93b","dweb:/ipfs/QmZPYmxrjB6SFWr5arTztrDofQ6XdyzXTUMeaQt5wcbv3T"],"license":"GPL-3.0-only"},"src/interfaces/IStateFingerpringComputer.sol":{"keccak256":"0xb2f72031bdd6b6ac7179ca9af90c290d37bcc43d6bab4db6e0b1ee7c7b4f72a2","urls":["bzz-raw://d8de3c648f1afab5458e553042a59b0df3d8d54be1a488e891de70821745da0c","dweb:/ipfs/QmQ6QoeMgZGdVjJ2aAt8t1AuBCJ95m6BRSR1GKRqVk4jct"],"license":"GPL-3.0-only"},"src/loan/lib/PWNFeeCalculator.sol":{"keccak256":"0xab8eb0be2d2e5a7c909a326de53459ae2ed6fd7cdd3985719515f279f952fcdf","urls":["bzz-raw://4ca7a9d230ab90b46cdb1a16bd99af5639af7adcf2250a20b7e1f77c952344f5","dweb:/ipfs/QmXzwraVHPmrVFtR4tkm5JqafygeDDvbQbkKu33EYUWLMq"],"license":"GPL-3.0-only"},"src/loan/lib/PWNSignatureChecker.sol":{"keccak256":"0xb76220c904f1b4c9e08166c4175746b161aaf70be14dc22b1a335f351970d1fd","urls":["bzz-raw://846d1cc6b7f1ba8b0bc6b5836aad018828bc1ad8f6f994ec59d24f6617d91fc1","dweb:/ipfs/QmWe7cAsDysa6Qjn9vBAiHW4iaPmZnaeVmqxnwRMikgSCM"],"license":"GPL-3.0-only"},"src/loan/terms/simple/loan/PWNSimpleLoan.sol":{"keccak256":"0xffcda7a3e69f344201705dc7a03bf8a82fd6a7df58d2e7d75abad2f700a60c80","urls":["bzz-raw://959899a8a7263f93a315e796fb4919ee05597da020a12de6267b6f53f4d1d129","dweb:/ipfs/QmaR7bRmqFobzDXp6i5Xuba47KF2rQ4dMKxyrupmteXSTP"],"license":"GPL-3.0-only"},"src/loan/terms/simple/proposal/PWNSimpleLoanProposal.sol":{"keccak256":"0x8a5203118fbf3bc7fb68a2454f86cc421487e2e1836b9cd023e1d55489e0ed96","urls":["bzz-raw://81898bdcd8895aa707576912e106d3a8352e52ca74b73345fb23c1ba18ecec13","dweb:/ipfs/QmPrHkndLgAjUkUiw9T84BLkpDfuKfNLbYsvd8CqAsYZhP"],"license":"GPL-3.0-only"},"src/loan/token/PWNLOAN.sol":{"keccak256":"0xc9cc3aa981692470d52f1fc2e2bf4b19238ca666457be95e0ab0c825eca8e6cb","urls":["bzz-raw://a22667800c0d58da6cbd6895ba8969ae4c13bf048605f6a4e6e4ff53875c0219","dweb:/ipfs/QmQFkh6xs9EMqtPD4YcFruvExv5CUjKVeHXNEJENbGShjo"],"license":"GPL-3.0-only"},"src/loan/vault/PWNVault.sol":{"keccak256":"0xf94e53ebc31e7c688b8af8236f52fdaf1112d0913936bc251bd4aad1658b1b0c","urls":["bzz-raw://0ff808cdf4e054760f2478c63a1fa0ac22e54c7043db6ccd6d7478a1db020e8b","dweb:/ipfs/QmNkJPdfxn1PqocRTatXGUabfQz2RL3q6qT2M9M3B863qq"],"license":"GPL-3.0-only"},"src/nonce/PWNRevokedNonce.sol":{"keccak256":"0x0e55f91dd6d6d807b5ef66c2d9cc676fe2e2f822b62f50fbb7596d64035f620e","urls":["bzz-raw://4fe70fc3862074acfd26fa0f49356e41661833e15816403bb657ea5e4851568f","dweb:/ipfs/QmTqs35QVCpXVUDvkc6S8zkrDJ2cbutsjhzVWYK2VqFZPS"],"license":"GPL-3.0-only"},"src/utilized-credit/PWNUtilizedCredit.sol":{"keccak256":"0xddfb750f98f42367f1895b96323e8867999d848c1b344d8a63a5be2ecb3b2ac3","urls":["bzz-raw://f803fde7175821839da65edf846b497b91cb33584e19cd04e9d805a8e7f98441","dweb:/ipfs/QmYW6CyNttnn9hnjtZd3vNUb7g2aqtdickdpy3SKak3wvC"],"license":"GPL-3.0-only"}},"version":1},"id":93} \ No newline at end of file +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_loanToken", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { + "internalType": "address", + "name": "_categoryRegistry", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { "inputs": [], "name": "CallerNotLOANTokenHolder", "type": "error" }, + { "inputs": [], "name": "CallerNotVault", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { "inputs": [], "name": "IncompleteTransfer", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "InterestAPROutOfBounds", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "InvalidDuration", + "type": "error" + }, + { "inputs": [], "name": "InvalidExtensionCaller", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "duration", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "InvalidExtensionDuration", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "allowed", "type": "address" }, + { "internalType": "address", "name": "current", "type": "address" } + ], + "name": "InvalidExtensionSigner", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "expected", "type": "bytes32" } + ], + "name": "InvalidLenderSpecHash", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint8", "name": "category", "type": "uint8" }, + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "InvalidMultiTokenAsset", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sourceOfFunds", "type": "address" } + ], + "name": "InvalidSourceOfFunds", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint40", "name": "timestap", "type": "uint40" } + ], + "name": "LoanDefaulted", + "type": "error" + }, + { "inputs": [], "name": "LoanNotAutoclaimable", "type": "error" }, + { "inputs": [], "name": "LoanNotRepaid", "type": "error" }, + { "inputs": [], "name": "LoanNotRunning", "type": "error" }, + { "inputs": [], "name": "LoanRepaid", "type": "error" }, + { "inputs": [], "name": "LoanRunning", "type": "error" }, + { "inputs": [], "name": "NonExistingLoan", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "currentBorrower", + "type": "address" + }, + { "internalType": "address", "name": "newBorrower", "type": "address" } + ], + "name": "RefinanceBorrowerMismatch", + "type": "error" + }, + { "inputs": [], "name": "RefinanceCollateralMismatch", "type": "error" }, + { "inputs": [], "name": "RefinanceCreditMismatch", "type": "error" }, + { + "inputs": [ + { "internalType": "uint8", "name": "categoryValue", "type": "uint8" } + ], + "name": "UnsupportedCategory", + "type": "error" + }, + { "inputs": [], "name": "UnsupportedTransferFunction", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "VaultTransferSameSourceAndDestination", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "extensionHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" }, + { + "internalType": "address", + "name": "compensationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compensationAmount", + "type": "uint256" + }, + { "internalType": "uint40", "name": "duration", "type": "uint40" }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoan.ExtensionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ExtensionProposalMade", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "loanId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "defaulted", + "type": "bool" + } + ], + "name": "LOANClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "loanId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposalContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoan.Terms", + "name": "terms", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "sourceOfFunds", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoan.LenderSpec", + "name": "lenderSpec", + "type": "tuple" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extra", + "type": "bytes" + } + ], + "name": "LOANCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "loanId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "originalDefaultTimestamp", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "extendedDefaultTimestamp", + "type": "uint40" + } + ], + "name": "LOANExtended", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "loanId", + "type": "uint256" + } + ], + "name": "LOANPaidBack", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct MultiToken.Asset", + "name": "asset", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "poolAdapter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "PoolSupply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct MultiToken.Asset", + "name": "asset", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "poolAdapter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "PoolWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct MultiToken.Asset", + "name": "asset", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "origin", + "type": "address" + } + ], + "name": "VaultPull", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct MultiToken.Asset", + "name": "asset", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "beneficiary", + "type": "address" + } + ], + "name": "VaultPush", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct MultiToken.Asset", + "name": "asset", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "beneficiary", + "type": "address" + } + ], + "name": "VaultPushFrom", + "type": "event" + }, + { + "inputs": [], + "name": "ACCRUING_INTEREST_APR_DECIMALS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ACCRUING_INTEREST_APR_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTENSION_PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ACCRUING_INTEREST_APR", + "outputs": [{ "internalType": "uint40", "name": "", "type": "uint40" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_EXTENSION_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINUTES_IN_YEAR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_EXTENSION_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_LOAN_DURATION", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "categoryRegistry", + "outputs": [ + { + "internalType": "contract IMultiTokenCategoryRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "name": "claimLOAN", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "proposalContract", + "type": "address" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "internalType": "struct PWNSimpleLoan.ProposalSpec", + "name": "proposalSpec", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "sourceOfFunds", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoan.LenderSpec", + "name": "lenderSpec", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bool", "name": "revokeNonce", "type": "bool" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "internalType": "struct PWNSimpleLoan.CallerSpec", + "name": "callerSpec", + "type": "tuple" + }, + { "internalType": "bytes", "name": "extra", "type": "bytes" } + ], + "name": "createLOAN", + "outputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" }, + { + "internalType": "address", + "name": "compensationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compensationAmount", + "type": "uint256" + }, + { "internalType": "uint40", "name": "duration", "type": "uint40" }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "internalType": "struct PWNSimpleLoan.ExtensionProposal", + "name": "extension", + "type": "tuple" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "extendLOAN", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "extensionProposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" }, + { + "internalType": "address", + "name": "compensationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compensationAmount", + "type": "uint256" + }, + { "internalType": "uint40", "name": "duration", "type": "uint40" }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "internalType": "struct PWNSimpleLoan.ExtensionProposal", + "name": "extension", + "type": "tuple" + } + ], + "name": "getExtensionHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "name": "getLOAN", + "outputs": [ + { "internalType": "uint8", "name": "status", "type": "uint8" }, + { "internalType": "uint40", "name": "startTimestamp", "type": "uint40" }, + { + "internalType": "uint40", + "name": "defaultTimestamp", + "type": "uint40" + }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "internalType": "address", + "name": "originalLender", + "type": "address" + }, + { "internalType": "address", "name": "loanOwner", "type": "address" }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "internalType": "address", + "name": "originalSourceOfFunds", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repaymentAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sourceOfFunds", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoan.LenderSpec", + "name": "lenderSpec", + "type": "tuple" + } + ], + "name": "getLenderSpecHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "getStateFingerprint", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "asset", + "type": "tuple" + } + ], + "name": "isValidAsset", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loanMetadataUri", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "name": "loanRepaymentAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loanToken", + "outputs": [ + { "internalType": "contract PWNLOAN", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" }, + { + "internalType": "address", + "name": "compensationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compensationAmount", + "type": "uint256" + }, + { "internalType": "uint40", "name": "duration", "type": "uint40" }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "internalType": "struct PWNSimpleLoan.ExtensionProposal", + "name": "extension", + "type": "tuple" + } + ], + "name": "makeExtensionProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC1155BatchReceived", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC1155Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" } + ], + "name": "repayLOAN", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loanId", "type": "uint256" }, + { "internalType": "uint256", "name": "creditAmount", "type": "uint256" }, + { "internalType": "address", "name": "loanOwner", "type": "address" } + ], + "name": "tryClaimRepaidLOAN", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/packages/subgraph/abis/SimpleLoanElasticChainlinkProposal.json b/packages/subgraph/abis/SimpleLoanElasticChainlinkProposal.json new file mode 100644 index 00000000..d2abe01f --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanElasticChainlinkProposal.json @@ -0,0 +1,1080 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { + "internalType": "address", + "name": "_utilizedCredit", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkFeedRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2SequencerUptimeFeed", + "type": "address" + }, + { "internalType": "address", "name": "_weth", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "AcceptorIsProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "CallerIsNotStatedProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "current", "type": "address" }, + { "internalType": "address", "name": "allowed", "type": "address" } + ], + "name": "CallerNotAllowedAcceptor", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "address", "name": "loanContract", "type": "address" } + ], + "name": "CallerNotLoanContract", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" } + ], + "name": "ChainlinkFeedPriceTooOld", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "int256", "name": "price", "type": "int256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" } + ], + "name": "ChainlinkFeedReturnedNegativePrice", + "type": "error" + }, + { "inputs": [], "name": "ChainlinkInvalidInputLenghts", "type": "error" }, + { + "inputs": [ + { "internalType": "uint32", "name": "defaultDate", "type": "uint32" }, + { "internalType": "uint32", "name": "current", "type": "uint32" } + ], + "name": "DefaultDateInPast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "timeSinceUp", "type": "uint256" }, + { "internalType": "uint256", "name": "gracePeriod", "type": "uint256" } + ], + "name": "GracePeriodNotOver", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "InsufficientCreditAmount", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "IntermediaryDenominationsOutOfBounds", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "proposed", "type": "bytes32" } + ], + "name": "InvalidCollateralStateFingerprint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + } + ], + "name": "InvalidRefinancingLoanId", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { "inputs": [], "name": "L2SequencerDown", "type": "error" }, + { "inputs": [], "name": "MinCreditAmountNotSet", "type": "error" }, + { "inputs": [], "name": "MissingStateFingerprintComputer", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ProposalMade", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOAN_TO_VALUE_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_INTERMEDIARY_DENOMINATIONS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "acceptor", "type": "address" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "acceptProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoan.Terms", + "name": "loanTerms", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkFeedRegistry", + "outputs": [ + { + "internalType": "contract IChainlinkFeedRegistryLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "proposalData", "type": "bytes" } + ], + "name": "decodeProposalData", + "outputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.Proposal", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + } + ], + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.ProposalValues", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.Proposal", + "name": "proposal", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + } + ], + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.ProposalValues", + "name": "proposalValues", + "type": "tuple" + } + ], + "name": "encodeProposalData", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "creditAddress", "type": "address" }, + { "internalType": "uint256", "name": "creditAmount", "type": "uint256" }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { "internalType": "bool[]", "name": "feedInvertFlags", "type": "bool[]" }, + { "internalType": "uint256", "name": "loanToValue", "type": "uint256" } + ], + "name": "getCollateralAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "multiproposalMerkleRoot", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoanProposal.Multiproposal", + "name": "multiproposal", + "type": "tuple" + } + ], + "name": "getMultiproposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "getProposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2SequencerUptimeFeed", + "outputs": [ + { + "internalType": "contract IChainlinkAggregatorLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticChainlinkProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "makeProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "proposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "revokeNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilizedCredit", + "outputs": [ + { + "internalType": "contract PWNUtilizedCredit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/abis/SimpleLoanElasticProposal.json b/packages/subgraph/abis/SimpleLoanElasticProposal.json new file mode 100644 index 00000000..797ae047 --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanElasticProposal.json @@ -0,0 +1,937 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { + "internalType": "address", + "name": "_utilizedCredit", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "AcceptorIsProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "CallerIsNotStatedProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "current", "type": "address" }, + { "internalType": "address", "name": "allowed", "type": "address" } + ], + "name": "CallerNotAllowedAcceptor", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "address", "name": "loanContract", "type": "address" } + ], + "name": "CallerNotLoanContract", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "defaultDate", "type": "uint32" }, + { "internalType": "uint32", "name": "current", "type": "uint32" } + ], + "name": "DefaultDateInPast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "InsufficientCreditAmount", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "proposed", "type": "bytes32" } + ], + "name": "InvalidCollateralStateFingerprint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + } + ], + "name": "InvalidRefinancingLoanId", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { "inputs": [], "name": "MinCreditAmountNotSet", "type": "error" }, + { "inputs": [], "name": "MissingStateFingerprintComputer", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { "inputs": [], "name": "ZeroCreditPerCollateralUnit", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditPerCollateralUnit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoanElasticProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ProposalMade", + "type": "event" + }, + { + "inputs": [], + "name": "CREDIT_PER_COLLATERAL_UNIT_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "acceptor", "type": "address" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "acceptProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoan.Terms", + "name": "loanTerms", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "proposalData", "type": "bytes" } + ], + "name": "decodeProposalData", + "outputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditPerCollateralUnit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticProposal.Proposal", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + } + ], + "internalType": "struct PWNSimpleLoanElasticProposal.ProposalValues", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditPerCollateralUnit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticProposal.Proposal", + "name": "proposal", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + } + ], + "internalType": "struct PWNSimpleLoanElasticProposal.ProposalValues", + "name": "proposalValues", + "type": "tuple" + } + ], + "name": "encodeProposalData", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "creditAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "creditPerCollateralUnit", + "type": "uint256" + } + ], + "name": "getCollateralAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "multiproposalMerkleRoot", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoanProposal.Multiproposal", + "name": "multiproposal", + "type": "tuple" + } + ], + "name": "getMultiproposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditPerCollateralUnit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "getProposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditPerCollateralUnit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanElasticProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "makeProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "proposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "revokeNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilizedCredit", + "outputs": [ + { + "internalType": "contract PWNUtilizedCredit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/abis/SimpleLoanListProposal.json b/packages/subgraph/abis/SimpleLoanListProposal.json new file mode 100644 index 00000000..6df56030 --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanListProposal.json @@ -0,0 +1,921 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { + "internalType": "address", + "name": "_utilizedCredit", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "AcceptorIsProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "CallerIsNotStatedProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "current", "type": "address" }, + { "internalType": "address", "name": "allowed", "type": "address" } + ], + "name": "CallerNotAllowedAcceptor", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "address", "name": "loanContract", "type": "address" } + ], + "name": "CallerNotLoanContract", + "type": "error" + }, + { + "inputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }], + "name": "CollateralIdNotWhitelisted", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "defaultDate", "type": "uint32" }, + { "internalType": "uint32", "name": "current", "type": "uint32" } + ], + "name": "DefaultDateInPast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "proposed", "type": "bytes32" } + ], + "name": "InvalidCollateralStateFingerprint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + } + ], + "name": "InvalidRefinancingLoanId", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { "inputs": [], "name": "MissingStateFingerprintComputer", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "collateralIdsWhitelistMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoanListProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ProposalMade", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "acceptor", "type": "address" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "acceptProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoan.Terms", + "name": "loanTerms", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "proposalData", "type": "bytes" } + ], + "name": "decodeProposalData", + "outputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "collateralIdsWhitelistMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanListProposal.Proposal", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "merkleInclusionProof", + "type": "bytes32[]" + } + ], + "internalType": "struct PWNSimpleLoanListProposal.ProposalValues", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "collateralIdsWhitelistMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanListProposal.Proposal", + "name": "proposal", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "merkleInclusionProof", + "type": "bytes32[]" + } + ], + "internalType": "struct PWNSimpleLoanListProposal.ProposalValues", + "name": "proposalValues", + "type": "tuple" + } + ], + "name": "encodeProposalData", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "multiproposalMerkleRoot", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoanProposal.Multiproposal", + "name": "multiproposal", + "type": "tuple" + } + ], + "name": "getMultiproposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "collateralIdsWhitelistMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanListProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "getProposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "collateralIdsWhitelistMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanListProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "makeProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "proposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "revokeNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilizedCredit", + "outputs": [ + { + "internalType": "contract PWNUtilizedCredit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/abis/SimpleLoanSimpleProposal.json b/packages/subgraph/abis/SimpleLoanSimpleProposal.json new file mode 100644 index 00000000..e106bea0 --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanSimpleProposal.json @@ -0,0 +1,882 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { + "internalType": "address", + "name": "_utilizedCredit", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "AcceptorIsProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "CallerIsNotStatedProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "current", "type": "address" }, + { "internalType": "address", "name": "allowed", "type": "address" } + ], + "name": "CallerNotAllowedAcceptor", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "address", "name": "loanContract", "type": "address" } + ], + "name": "CallerNotLoanContract", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "defaultDate", "type": "uint32" }, + { "internalType": "uint32", "name": "current", "type": "uint32" } + ], + "name": "DefaultDateInPast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "proposed", "type": "bytes32" } + ], + "name": "InvalidCollateralStateFingerprint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + } + ], + "name": "InvalidRefinancingLoanId", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { "inputs": [], "name": "MissingStateFingerprintComputer", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoanSimpleProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ProposalMade", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "acceptor", "type": "address" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "acceptProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoan.Terms", + "name": "loanTerms", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "proposalData", "type": "bytes" } + ], + "name": "decodeProposalData", + "outputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanSimpleProposal.Proposal", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanSimpleProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "encodeProposalData", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "multiproposalMerkleRoot", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoanProposal.Multiproposal", + "name": "multiproposal", + "type": "tuple" + } + ], + "name": "getMultiproposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanSimpleProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "getProposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "collateralCategory", + "type": "uint8" + }, + { + "internalType": "address", + "name": "collateralAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "checkCollateralStateFingerprint", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "collateralStateFingerprint", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "allowedAcceptor", + "type": "address" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanSimpleProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "makeProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "proposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "revokeNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilizedCredit", + "outputs": [ + { + "internalType": "contract PWNUtilizedCredit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/config/mainnet.json b/packages/subgraph/config/mainnet.json index ce20304b..c27e4248 100644 --- a/packages/subgraph/config/mainnet.json +++ b/packages/subgraph/config/mainnet.json @@ -1,5 +1,43 @@ { - "network": "mainnet", - "SimpleLoanAddress": "0x719A69d0dc67bd3Aa7648D4694081B3c87952797", - "SimpleLoanStartBlock": 21628749 - } \ No newline at end of file + "network": "mainnet", + "SimpleLoanSimpleProposal": { + "address": "0xe624E7D33baC728bE2bdB606Da0018B6E05A84D9", + "startBlock": 21628752 + }, + "SimpleLoanListProposal": { + "address": "0x7160Ec33788Df9AFb8AAEe777e7Ae21151B51eDd", + "startBlock": 21628752 + }, + "SimpleLoanElasticProposal": { + "address": "0xeC6390D4B22FFfD22E5C5FDB56DaF653C3Cd0626", + "startBlock": 21628752 + }, + "SimpleLoanElasticChainlinkProposal": { + "address": "0xBA58E16BE93dAdcBB74a194bDfD9E5933b24016B", + "startBlock": 21772404 + }, + "SimpleLoan": { + "address": "0x719A69d0dc67bd3Aa7648D4694081B3c87952797", + "startBlock": 21628749 + }, + "LoanToken": { + "address": "0x4440C069272cC34b80C7B11bEE657D0349Ba9C23", + "startBlock": 17289963 + }, + "Config": { + "address": "0xd52a2898d61636bB3eEF0d145f05352FF543bdCC", + "startBlock": 20046912 + }, + "Hub": { + "address": "0x37807A2F031b3B44081F4b21500E5D70EbaDAdd5", + "startBlock": 17289963 + }, + "ChainlinkFeedRegistry": { + "address": "0x8D5e90706E52a52853dA9A14fA1c63889a412851", + "startBlock": 21772404 + }, + "MultiTokenCategoryRegistry": { + "address": "0xbB2168d5546A94AE2DA9254e63D88F7f137B2534", + "startBlock": 20047106 + } +} \ No newline at end of file diff --git a/packages/subgraph/config/sepolia.json b/packages/subgraph/config/sepolia.json index 1d54d07c..bb3c6f67 100644 --- a/packages/subgraph/config/sepolia.json +++ b/packages/subgraph/config/sepolia.json @@ -1,5 +1,43 @@ { - "network": "sepolia", - "SimpleLoanAddress": "0x719A69d0dc67bd3Aa7648D4694081B3c87952797", - "SimpleLoanStartBlock": 7298850 - } \ No newline at end of file + "network": "sepolia", + "SimpleLoanSimpleProposal": { + "address": "0xe624E7D33baC728bE2bdB606Da0018B6E05A84D9", + "startBlock": 7298850 + }, + "SimpleLoanListProposal": { + "address": "0x7160Ec33788Df9AFb8AAEe777e7Ae21151B51eDd", + "startBlock": 7298850 + }, + "SimpleLoanElasticProposal": { + "address": "0xeC6390D4B22FFfD22E5C5FDB56DaF653C3Cd0626", + "startBlock": 7298851 + }, + "SimpleLoanElasticChainlinkProposal": { + "address": "0xC46170F43b97faE1A8B507d6fdDaFfBb7527D61B", + "startBlock": 8069855 + }, + "SimpleLoan": { + "address": "0x719A69d0dc67bd3Aa7648D4694081B3c87952797", + "startBlock": 7298850 + }, + "LoanToken": { + "address": "0x4440C069272cC34b80C7B11bEE657D0349Ba9C23", + "startBlock": 4435806 + }, + "Config": { + "address": "0xd52a2898d61636bB3eEF0d145f05352FF543bdCC", + "startBlock": 5953668 + }, + "Hub": { + "address": "0x37807A2F031b3B44081F4b21500E5D70EbaDAdd5", + "startBlock": 4435806 + }, + "ChainlinkFeedRegistry": { + "address": "0x8D5e90706E52a52853dA9A14fA1c63889a412851", + "startBlock": 7298850 + }, + "MultiTokenCategoryRegistry": { + "address": "0xbB2168d5546A94AE2DA9254e63D88F7f137B2534", + "startBlock": 5953672 + } +} \ No newline at end of file diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index eb4b837c..aab3bb93 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -13,6 +13,13 @@ type Asset @entity(immutable: true) { amount: BigDecimal! } +enum LoanStatus { + Active + Repaid + Defaulted + Claimed +} + type Loan @entity(immutable: false) { # Combination of chainId and loanId from contract id: String! @@ -39,14 +46,516 @@ type Loan @entity(immutable: false) { # Duration duration: BigInt! + # Default deadline timestamp (createdAt + duration) + defaultDeadline: BigInt! + # Collateral collateral: Asset! # Credit credit: Asset! - # Status might be ACTIVE, REPAID, DEFAULTED, CLAIMED - status: String! + status: LoanStatus! extra: Bytes! + + # TODO also add Loan contract version? +} + +# TODO add version + +type ProposalMade @entity(immutable: true) { + id: Bytes! + proposalHash: Bytes! # bytes32 + proposer: Bytes! # address + proposal_collateralCategory: Int! # uint8 + proposal_collateralAddress: Bytes! # address + proposal_collateralId: BigInt! # uint256 + proposal_collateralAmount: BigInt! # uint256 + proposal_checkCollateralStateFingerprint: Boolean! # bool + proposal_collateralStateFingerprint: Bytes! # bytes32 + proposal_creditAddress: Bytes! # address + proposal_creditAmount: BigInt! # uint256 + proposal_availableCreditLimit: BigInt! # uint256 + proposal_utilizedCreditId: Bytes! # bytes32 + proposal_fixedInterestAmount: BigInt! # uint256 + proposal_accruingInterestAPR: Int! # uint24 + proposal_durationOrDate: BigInt! # uint32 + proposal_expiration: BigInt! # uint40 + proposal_allowedAcceptor: Bytes! # address + proposal_proposer: Bytes! # address + proposal_proposerSpecHash: Bytes! # bytes32 + proposal_isOffer: Boolean! # bool + proposal_refinancingLoanId: BigInt! # uint256 + proposal_nonceSpace: BigInt! # uint256 + proposal_nonce: BigInt! # uint256 + proposal_loanContract: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type SimpleLoanListProposalProposalMade @entity(immutable: true) { + id: Bytes! + proposalHash: Bytes! # bytes32 + proposer: Bytes! # address + proposal_collateralCategory: Int! # uint8 + proposal_collateralAddress: Bytes! # address + proposal_collateralIdsWhitelistMerkleRoot: Bytes! # bytes32 + proposal_collateralAmount: BigInt! # uint256 + proposal_checkCollateralStateFingerprint: Boolean! # bool + proposal_collateralStateFingerprint: Bytes! # bytes32 + proposal_creditAddress: Bytes! # address + proposal_creditAmount: BigInt! # uint256 + proposal_availableCreditLimit: BigInt! # uint256 + proposal_utilizedCreditId: Bytes! # bytes32 + proposal_fixedInterestAmount: BigInt! # uint256 + proposal_accruingInterestAPR: Int! # uint24 + proposal_durationOrDate: BigInt! # uint32 + proposal_expiration: BigInt! # uint40 + proposal_allowedAcceptor: Bytes! # address + proposal_proposer: Bytes! # address + proposal_proposerSpecHash: Bytes! # bytes32 + proposal_isOffer: Boolean! # bool + proposal_refinancingLoanId: BigInt! # uint256 + proposal_nonceSpace: BigInt! # uint256 + proposal_nonce: BigInt! # uint256 + proposal_loanContract: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type SimpleLoanElasticProposalProposalMade @entity(immutable: true) { + id: Bytes! + proposalHash: Bytes! # bytes32 + proposer: Bytes! # address + proposal_collateralCategory: Int! # uint8 + proposal_collateralAddress: Bytes! # address + proposal_collateralId: BigInt! # uint256 + proposal_checkCollateralStateFingerprint: Boolean! # bool + proposal_collateralStateFingerprint: Bytes! # bytes32 + proposal_creditAddress: Bytes! # address + proposal_creditPerCollateralUnit: BigInt! # uint256 + proposal_minCreditAmount: BigInt! # uint256 + proposal_availableCreditLimit: BigInt! # uint256 + proposal_utilizedCreditId: Bytes! # bytes32 + proposal_fixedInterestAmount: BigInt! # uint256 + proposal_accruingInterestAPR: Int! # uint24 + proposal_durationOrDate: BigInt! # uint32 + proposal_expiration: BigInt! # uint40 + proposal_allowedAcceptor: Bytes! # address + proposal_proposer: Bytes! # address + proposal_proposerSpecHash: Bytes! # bytes32 + proposal_isOffer: Boolean! # bool + proposal_refinancingLoanId: BigInt! # uint256 + proposal_nonceSpace: BigInt! # uint256 + proposal_nonce: BigInt! # uint256 + proposal_loanContract: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type SimpleLoanElasticChainlinkProposalProposalMade @entity(immutable: true) { + id: Bytes! + proposalHash: Bytes! # bytes32 + proposer: Bytes! # address + proposal_collateralCategory: Int! # uint8 + proposal_collateralAddress: Bytes! # address + proposal_collateralId: BigInt! # uint256 + proposal_checkCollateralStateFingerprint: Boolean! # bool + proposal_collateralStateFingerprint: Bytes! # bytes32 + proposal_creditAddress: Bytes! # address + proposal_feedIntermediaryDenominations: [Bytes!]! # address[] + proposal_feedInvertFlags: [Boolean!]! # bool[] + proposal_loanToValue: BigInt! # uint256 + proposal_minCreditAmount: BigInt! # uint256 + proposal_availableCreditLimit: BigInt! # uint256 + proposal_utilizedCreditId: Bytes! # bytes32 + proposal_fixedInterestAmount: BigInt! # uint256 + proposal_accruingInterestAPR: Int! # uint24 + proposal_durationOrDate: BigInt! # uint32 + proposal_expiration: BigInt! # uint40 + proposal_allowedAcceptor: Bytes! # address + proposal_proposer: Bytes! # address + proposal_proposerSpecHash: Bytes! # bytes32 + proposal_isOffer: Boolean! # bool + proposal_refinancingLoanId: BigInt! # uint256 + proposal_nonceSpace: BigInt! # uint256 + proposal_nonce: BigInt! # uint256 + proposal_loanContract: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type ExtensionProposalMade @entity(immutable: true) { + id: Bytes! + extensionHash: Bytes! # bytes32 + proposer: Bytes! # address + proposal_loanId: BigInt! # uint256 + proposal_compensationAddress: Bytes! # address + proposal_compensationAmount: BigInt! # uint256 + proposal_duration: BigInt! # uint40 + proposal_expiration: BigInt! # uint40 + proposal_proposer: Bytes! # address + proposal_nonceSpace: BigInt! # uint256 + proposal_nonce: BigInt! # uint256 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANClaimed @entity(immutable: true) { + id: Bytes! + loanId: BigInt! # uint256 + defaulted: Boolean! # bool + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANCreated @entity(immutable: true) { + id: Bytes! + loanId: BigInt! # uint256 + proposalHash: Bytes! # bytes32 + proposalContract: Bytes! # address + refinancingLoanId: BigInt! # uint256 + terms_lender: Bytes! # address + terms_borrower: Bytes! # address + terms_duration: BigInt! # uint32 + terms_collateral_category: Int! # uint8 + terms_collateral_assetAddress: Bytes! # address + terms_collateral_id: BigInt! # uint256 + terms_collateral_amount: BigInt! # uint256 + terms_credit_category: Int! # uint8 + terms_credit_assetAddress: Bytes! # address + terms_credit_id: BigInt! # uint256 + terms_credit_amount: BigInt! # uint256 + terms_fixedInterestAmount: BigInt! # uint256 + terms_accruingInterestAPR: Int! # uint24 + terms_lenderSpecHash: Bytes! # bytes32 + terms_borrowerSpecHash: Bytes! # bytes32 + lenderSpec_sourceOfFunds: Bytes! # address + extra: Bytes! # bytes + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANExtended @entity(immutable: true) { + id: Bytes! + loanId: BigInt! # uint256 + originalDefaultTimestamp: BigInt! # uint40 + extendedDefaultTimestamp: BigInt! # uint40 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANPaidBack @entity(immutable: true) { + id: Bytes! + loanId: BigInt! # uint256 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type PoolSupply @entity(immutable: true) { + id: Bytes! + asset_category: Int! # uint8 + asset_assetAddress: Bytes! # address + asset_id: BigInt! # uint256 + asset_amount: BigInt! # uint256 + poolAdapter: Bytes! # address + pool: Bytes! # address + owner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type PoolWithdraw @entity(immutable: true) { + id: Bytes! + asset_category: Int! # uint8 + asset_assetAddress: Bytes! # address + asset_id: BigInt! # uint256 + asset_amount: BigInt! # uint256 + poolAdapter: Bytes! # address + pool: Bytes! # address + owner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type VaultPull @entity(immutable: true) { + id: Bytes! + asset_category: Int! # uint8 + asset_assetAddress: Bytes! # address + asset_id: BigInt! # uint256 + asset_amount: BigInt! # uint256 + origin: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type VaultPush @entity(immutable: true) { + id: Bytes! + asset_category: Int! # uint8 + asset_assetAddress: Bytes! # address + asset_id: BigInt! # uint256 + asset_amount: BigInt! # uint256 + beneficiary: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type VaultPushFrom @entity(immutable: true) { + id: Bytes! + asset_category: Int! # uint8 + asset_assetAddress: Bytes! # address + asset_id: BigInt! # uint256 + asset_amount: BigInt! # uint256 + origin: Bytes! # address + beneficiary: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type Approval @entity(immutable: true) { + id: Bytes! + owner: Bytes! # address + approved: Bytes! # address + tokenId: BigInt! # uint256 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type ApprovalForAll @entity(immutable: true) { + id: Bytes! + owner: Bytes! # address + operator: Bytes! # address + approved: Boolean! # bool + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANBurned @entity(immutable: true) { + id: Bytes! + loanId: BigInt! # uint256 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANMinted @entity(immutable: true) { + id: Bytes! + loanId: BigInt! # uint256 + loanContract: Bytes! # address + owner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type Transfer @entity(immutable: true) { + id: Bytes! + from: Bytes! # address + to: Bytes! # address + tokenId: BigInt! # uint256 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type AdminChanged @entity(immutable: true) { + id: Bytes! + previousAdmin: Bytes! # address + newAdmin: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type BeaconUpgraded @entity(immutable: true) { + id: Bytes! + beacon: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type Upgraded @entity(immutable: true) { + id: Bytes! + implementation: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type OwnershipTransferStarted @entity(immutable: true) { + id: Bytes! + previousOwner: Bytes! # address + newOwner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type OwnershipTransferred @entity(immutable: true) { + id: Bytes! + previousOwner: Bytes! # address + newOwner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type TagSet @entity(immutable: true) { + id: Bytes! + _address: Bytes! # address + tag: Bytes! # bytes32 + hasTag: Boolean! # bool + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type DefaultLOANMetadataUriUpdated @entity(immutable: true) { + id: Bytes! + newUri: String! # string + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type FeeCollectorUpdated @entity(immutable: true) { + id: Bytes! + oldFeeCollector: Bytes! # address + newFeeCollector: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type FeeUpdated @entity(immutable: true) { + id: Bytes! + oldFee: Int! # uint16 + newFee: Int! # uint16 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type Initialized @entity(immutable: true) { + id: Bytes! + version: Int! # uint8 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type LOANMetadataUriUpdated @entity(immutable: true) { + id: Bytes! + loanContract: Bytes! # address + newUri: String! # string + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type ConfigOwnershipTransferStarted @entity(immutable: true) { + id: Bytes! + previousOwner: Bytes! # address + newOwner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type ConfigOwnershipTransferred @entity(immutable: true) { + id: Bytes! + previousOwner: Bytes! # address + newOwner: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} +type AccessControllerSet @entity(immutable: true) { + id: Bytes! + accessController: Bytes! # address + sender: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type FeedConfirmed @entity(immutable: true) { + id: Bytes! + asset: Bytes! # address + denomination: Bytes! # address + latestAggregator: Bytes! # address + previousAggregator: Bytes! # address + nextPhaseId: Int! # uint16 + sender: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type FeedProposed @entity(immutable: true) { + id: Bytes! + asset: Bytes! # address + denomination: Bytes! # address + proposedAggregator: Bytes! # address + currentAggregator: Bytes! # address + sender: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type OwnershipTransferRequested @entity(immutable: true) { + id: Bytes! + from: Bytes! # address + to: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type ChainlinkFeedRegistryOwnershipTransferred @entity(immutable: true) { + id: Bytes! + from: Bytes! # address + to: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type Category @entity(immutable: true) { + # TODO can we make this Bytes? + id: Int! # category id +} + +type AssetCategory @entity(immutable: true) { + id: Bytes! # asset address + category: Category! +} + +type CategoryRegistered @entity(immutable: true) { + id: Bytes! + assetAddress: Bytes! # address + category: Int! # uint8 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type CategoryUnregistered @entity(immutable: true) { + id: Bytes! + assetAddress: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! } diff --git a/packages/subgraph/src/chainlink-feed-registry.ts b/packages/subgraph/src/chainlink-feed-registry.ts new file mode 100644 index 00000000..1954fa7e --- /dev/null +++ b/packages/subgraph/src/chainlink-feed-registry.ts @@ -0,0 +1,97 @@ +import { + AccessControllerSet as AccessControllerSetEvent, + FeedConfirmed as FeedConfirmedEvent, + FeedProposed as FeedProposedEvent, + OwnershipTransferRequested as OwnershipTransferRequestedEvent, + OwnershipTransferred as OwnershipTransferredEvent, +} from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" +import { + AccessControllerSet, + FeedConfirmed, + FeedProposed, + OwnershipTransferRequested, + OwnershipTransferred, +} from "../generated/schema" + +export function handleAccessControllerSet( + event: AccessControllerSetEvent, +): void { + const entity = new AccessControllerSet( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.accessController = event.params.accessController + entity.sender = event.params.sender + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleFeedConfirmed(event: FeedConfirmedEvent): void { + const entity = new FeedConfirmed( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset = event.params.asset + entity.denomination = event.params.denomination + entity.latestAggregator = event.params.latestAggregator + entity.previousAggregator = event.params.previousAggregator + entity.nextPhaseId = event.params.nextPhaseId + entity.sender = event.params.sender + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleFeedProposed(event: FeedProposedEvent): void { + const entity = new FeedProposed( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset = event.params.asset + entity.denomination = event.params.denomination + entity.proposedAggregator = event.params.proposedAggregator + entity.currentAggregator = event.params.currentAggregator + entity.sender = event.params.sender + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferRequested( + event: OwnershipTransferRequestedEvent, +): void { + const entity = new OwnershipTransferRequested( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.from = event.params.from + entity.to = event.params.to + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferred( + event: OwnershipTransferredEvent, +): void { + const entity = new OwnershipTransferred( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.from = event.params.from + entity.to = event.params.to + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/config.ts b/packages/subgraph/src/config.ts new file mode 100644 index 00000000..810a804a --- /dev/null +++ b/packages/subgraph/src/config.ts @@ -0,0 +1,170 @@ +import { + AdminChanged as AdminChangedEvent, + BeaconUpgraded as BeaconUpgradedEvent, + Upgraded as UpgradedEvent, + DefaultLOANMetadataUriUpdated as DefaultLOANMetadataUriUpdatedEvent, + FeeCollectorUpdated as FeeCollectorUpdatedEvent, + FeeUpdated as FeeUpdatedEvent, + Initialized as InitializedEvent, + LOANMetadataUriUpdated as LOANMetadataUriUpdatedEvent, + OwnershipTransferStarted as OwnershipTransferStartedEvent, + OwnershipTransferred as OwnershipTransferredEvent, +} from "../generated/Config/Config" +import { + AdminChanged, + BeaconUpgraded, + Upgraded, + DefaultLOANMetadataUriUpdated, + FeeCollectorUpdated, + FeeUpdated, + Initialized, + LOANMetadataUriUpdated, + OwnershipTransferStarted, + OwnershipTransferred, +} from "../generated/schema" + +export function handleAdminChanged(event: AdminChangedEvent): void { + const entity = new AdminChanged( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousAdmin = event.params.previousAdmin + entity.newAdmin = event.params.newAdmin + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleBeaconUpgraded(event: BeaconUpgradedEvent): void { + const entity = new BeaconUpgraded( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.beacon = event.params.beacon + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleUpgraded(event: UpgradedEvent): void { + const entity = new Upgraded( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.implementation = event.params.implementation + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleDefaultLOANMetadataUriUpdated( + event: DefaultLOANMetadataUriUpdatedEvent, +): void { + const entity = new DefaultLOANMetadataUriUpdated( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.newUri = event.params.newUri + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleFeeCollectorUpdated( + event: FeeCollectorUpdatedEvent, +): void { + const entity = new FeeCollectorUpdated( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.oldFeeCollector = event.params.oldFeeCollector + entity.newFeeCollector = event.params.newFeeCollector + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleFeeUpdated(event: FeeUpdatedEvent): void { + const entity = new FeeUpdated( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.oldFee = event.params.oldFee + entity.newFee = event.params.newFee + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleInitialized(event: InitializedEvent): void { + const entity = new Initialized( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.version = event.params.version + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANMetadataUriUpdated( + event: LOANMetadataUriUpdatedEvent, +): void { + const entity = new LOANMetadataUriUpdated( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanContract = event.params.loanContract + entity.newUri = event.params.newUri + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferStarted( + event: OwnershipTransferStartedEvent, +): void { + const entity = new OwnershipTransferStarted( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousOwner = event.params.previousOwner + entity.newOwner = event.params.newOwner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferred( + event: OwnershipTransferredEvent, +): void { + const entity = new OwnershipTransferred( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousOwner = event.params.previousOwner + entity.newOwner = event.params.newOwner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/contract.ts b/packages/subgraph/src/contract.ts deleted file mode 100644 index e407fd87..00000000 --- a/packages/subgraph/src/contract.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { - Account, - ERC20Balance, - Loan, - NFTAttribute, - NFTBalance, - NFTMetadata, - Proposal, -} from "../generated/subgraph-QmXpWoxzBQ3dvDK3WTVAyMuEtDvm4UgqLWo7kFS4M6WXnh"; - -export function handleAccount(entity: Account): void { - // Empty handler for Account -} - -export function handleProposal(entity: Proposal): void { - // Empty handler for Proposal -} - -export function handleLoan(entity: Loan): void { - // Empty handler for Loan -} - -export function handleERC20Balance(entity: ERC20Balance): void { - // Empty handler for ERC20Balance -} - -export function handleNFTBalance(entity: NFTBalance): void { - // Empty handler for NFTBalance -} - -export function handleNFTMetadata(entity: NFTMetadata): void { - // Empty handler for NFTMetadata -} - -export function handleNFTAttribute(entity: NFTAttribute): void { - // Empty handler for NFTAttribute -} diff --git a/packages/subgraph/src/hub.ts b/packages/subgraph/src/hub.ts new file mode 100644 index 00000000..2f908fc1 --- /dev/null +++ b/packages/subgraph/src/hub.ts @@ -0,0 +1,57 @@ +import { + OwnershipTransferStarted as OwnershipTransferStartedEvent, + OwnershipTransferred as OwnershipTransferredEvent, + TagSet as TagSetEvent, +} from "../generated/Hub/Hub" +import { + OwnershipTransferStarted, + OwnershipTransferred, + TagSet, +} from "../generated/schema" + +export function handleOwnershipTransferStarted( + event: OwnershipTransferStartedEvent, +): void { + const entity = new OwnershipTransferStarted( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousOwner = event.params.previousOwner + entity.newOwner = event.params.newOwner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferred( + event: OwnershipTransferredEvent, +): void { + const entity = new OwnershipTransferred( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousOwner = event.params.previousOwner + entity.newOwner = event.params.newOwner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleTagSet(event: TagSetEvent): void { + const entity = new TagSet( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity._address = event.params._address + entity.tag = event.params.tag + entity.hasTag = event.params.hasTag + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/loan-mapping.ts b/packages/subgraph/src/loan-mapping.ts index c26a219e..04a71040 100644 --- a/packages/subgraph/src/loan-mapping.ts +++ b/packages/subgraph/src/loan-mapping.ts @@ -1,5 +1,5 @@ -import { Address, BigDecimal } from "@graphprotocol/graph-ts"; -import { LOANClaimed, LOANCreated, LOANPaidBack, LOANCreatedTermsCollateralStruct, LOANCreatedTermsCreditStruct } from "../generated/PWN_SimpleLoan/SimpleLoan"; // Path to generated code +import { Address, BigDecimal, BigInt } from "@graphprotocol/graph-ts"; +import { LOANClaimed, LOANCreated, LOANPaidBack, LOANCreatedTermsCollateralStruct, LOANCreatedTermsCreditStruct, LOANExtended } from "../generated/SimpleLoan/SimpleLoan"; // Path to generated code import { Account, Asset, Loan } from "../generated/schema"; // Helper to get or create an Account entity @@ -40,6 +40,39 @@ function getOrCreateCreditAsset(asset: LOANCreatedTermsCreditStruct): Asset { return creditAsset; } +// Helper function to check if a loan should be considered defaulted based on time +function isLoanDefaulted(loan: Loan, currentTimestamp: BigInt): boolean { + // Only check for default if loan is still active + if (loan.status != "Active") { + return false; + } + + // Calculate default deadline: createdAt + duration + const defaultDeadline = loan.createdAt.plus(loan.duration); + + // Loan is defaulted if current time is past the deadline + return currentTimestamp.gt(defaultDeadline); +} + +// Helper function to update loan status based on time +function updateLoanStatusIfDefaulted(loan: Loan, currentTimestamp: BigInt): void { + if (isLoanDefaulted(loan, currentTimestamp)) { + loan.status = "Defaulted"; + } +} + +// Helper function to check and update multiple loans for defaults +// This can be called from any event handler to update loan statuses +function checkAndUpdateLoansForDefaults(currentTimestamp: BigInt, loanIds: string[]): void { + for (let i = 0; i < loanIds.length; i++) { + const loan = Loan.load(loanIds[i]); + if (loan && loan.status == "Active") { + updateLoanStatusIfDefaulted(loan, currentTimestamp); + loan.save(); + } + } +} + export function handleLOANCreated(event: LOANCreated): void { const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; const loan = new Loan(loanEntityId); @@ -58,10 +91,12 @@ export function handleLOANCreated(event: LOANCreated): void { // terms setting loan.duration = terms.duration; + // Calculate and store the default deadline for easier querying + // loan.defaultDeadline = event.block.timestamp.plus(terms.duration); // Uncomment after codegen loan.collateral = getOrCreateCollateralAsset(terms.collateral).id; loan.credit = getOrCreateCreditAsset(terms.credit).id; - loan.status = "ACTIVE"; + loan.status = "Active"; loan.extra = event.params.extra; @@ -74,20 +109,42 @@ export function handleLOANPaidBack(event: LOANPaidBack): void { const loan = Loan.load(loanEntityId); if (!loan) return; - loan.status = "REPAID"; + loan.status = "Repaid"; loan.save(); // TODO: Update the linked Proposal entity status } +// Updated function to handle both explicit defaults and time-based defaults export function handleLOANClaimed(event: LOANClaimed): void { const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; const loan = Loan.load(loanEntityId); if (!loan) return; if (event.params.defaulted) { - loan.status = "DEFAULTED"; + loan.status = "Defaulted"; + } else { + // Even if not explicitly defaulted, check if it should be considered defaulted based on time + updateLoanStatusIfDefaulted(loan, event.block.timestamp); } loan.save(); } + +// New handler for loan extensions - this updates the default deadline +export function handleLOANExtended(event: LOANExtended): void { + const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; + const loan = Loan.load(loanEntityId); + if (!loan) return; + + // Update the duration to reflect the extension + // The new default deadline is the extendedDefaultTimestamp + const originalDeadline = loan.createdAt.plus(loan.duration); + const extensionDuration = event.params.extendedDefaultTimestamp.minus(originalDeadline); + loan.duration = loan.duration.plus(extensionDuration); + + // Update default deadline if the field is available after codegen + // loan.defaultDeadline = event.params.extendedDefaultTimestamp; + + loan.save(); +} diff --git a/packages/subgraph/src/loan-token.ts b/packages/subgraph/src/loan-token.ts new file mode 100644 index 00000000..f8758a19 --- /dev/null +++ b/packages/subgraph/src/loan-token.ts @@ -0,0 +1,87 @@ +import { + Approval as ApprovalEvent, + ApprovalForAll as ApprovalForAllEvent, + LOANBurned as LOANBurnedEvent, + LOANMinted as LOANMintedEvent, + Transfer as TransferEvent, +} from "../generated/LoanToken/LoanToken" +import { + Approval, + ApprovalForAll, + LOANBurned, + LOANMinted, + Transfer, +} from "../generated/schema" + +export function handleApproval(event: ApprovalEvent): void { + const entity = new Approval( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.owner = event.params.owner + entity.approved = event.params.approved + entity.tokenId = event.params.tokenId + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleApprovalForAll(event: ApprovalForAllEvent): void { + const entity = new ApprovalForAll( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.owner = event.params.owner + entity.operator = event.params.operator + entity.approved = event.params.approved + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANBurned(event: LOANBurnedEvent): void { + const entity = new LOANBurned( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanId = event.params.loanId + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANMinted(event: LOANMintedEvent): void { + const entity = new LOANMinted( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanId = event.params.loanId + entity.loanContract = event.params.loanContract + entity.owner = event.params.owner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleTransfer(event: TransferEvent): void { + const entity = new Transfer( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.from = event.params.from + entity.to = event.params.to + entity.tokenId = event.params.tokenId + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/multi-token-category-registry.ts b/packages/subgraph/src/multi-token-category-registry.ts new file mode 100644 index 00000000..d39bbe47 --- /dev/null +++ b/packages/subgraph/src/multi-token-category-registry.ts @@ -0,0 +1,83 @@ +import { + CategoryRegistered as CategoryRegisteredEvent, + CategoryUnregistered as CategoryUnregisteredEvent, + OwnershipTransferStarted as OwnershipTransferStartedEvent, + OwnershipTransferred as OwnershipTransferredEvent, +} from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" +import { + CategoryRegistered, + CategoryUnregistered, + OwnershipTransferStarted, + OwnershipTransferred, + Category, + AssetCategory, +} from "../generated/schema" +import { store } from '@graphprotocol/graph-ts' + +export function handleCategoryRegistered(event: CategoryRegisteredEvent): void { + let category = Category.load(event.params.category) + if (category == null) { + category = new Category(event.params.category) + category.save() + } + let assetCategory = Category.load() + + const entity = new CategoryRegistered( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.assetAddress = event.params.assetAddress + entity.category = event.params.category + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleCategoryUnregistered( + event: CategoryUnregisteredEvent, +): void { + const entity = new CategoryUnregistered( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.assetAddress = event.params.assetAddress + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferStarted( + event: OwnershipTransferStartedEvent, +): void { + const entity = new OwnershipTransferStarted( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousOwner = event.params.previousOwner + entity.newOwner = event.params.newOwner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleOwnershipTransferred( + event: OwnershipTransferredEvent, +): void { + const entity = new OwnershipTransferred( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.previousOwner = event.params.previousOwner + entity.newOwner = event.params.newOwner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts new file mode 100644 index 00000000..5d55f482 --- /dev/null +++ b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts @@ -0,0 +1,48 @@ +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" +import { SimpleLoanElasticChainlinkProposalProposalMade } from "../generated/schema" +import { Bytes } from "@graphprotocol/graph-ts" + +export function handleProposalMade(event: ProposalMadeEvent): void { + const entity = new SimpleLoanElasticChainlinkProposalProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.proposalHash = event.params.proposalHash + entity.proposer = event.params.proposer + entity.proposal_collateralCategory = event.params.proposal.collateralCategory + entity.proposal_collateralAddress = event.params.proposal.collateralAddress + entity.proposal_collateralId = event.params.proposal.collateralId + entity.proposal_checkCollateralStateFingerprint = + event.params.proposal.checkCollateralStateFingerprint + entity.proposal_collateralStateFingerprint = + event.params.proposal.collateralStateFingerprint + entity.proposal_creditAddress = event.params.proposal.creditAddress + entity.proposal_feedIntermediaryDenominations = changetype( + event.params.proposal.feedIntermediaryDenominations, + ) + entity.proposal_feedInvertFlags = event.params.proposal.feedInvertFlags + entity.proposal_loanToValue = event.params.proposal.loanToValue + entity.proposal_minCreditAmount = event.params.proposal.minCreditAmount + entity.proposal_availableCreditLimit = + event.params.proposal.availableCreditLimit + entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId + entity.proposal_fixedInterestAmount = + event.params.proposal.fixedInterestAmount + entity.proposal_accruingInterestAPR = + event.params.proposal.accruingInterestAPR + entity.proposal_durationOrDate = event.params.proposal.durationOrDate + entity.proposal_expiration = event.params.proposal.expiration + entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor + entity.proposal_proposer = event.params.proposal.proposer + entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash + entity.proposal_isOffer = event.params.proposal.isOffer + entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId + entity.proposal_nonceSpace = event.params.proposal.nonceSpace + entity.proposal_nonce = event.params.proposal.nonce + entity.proposal_loanContract = event.params.proposal.loanContract + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/simple-loan-elastic-proposal.ts b/packages/subgraph/src/simple-loan-elastic-proposal.ts new file mode 100644 index 00000000..a1ca09a2 --- /dev/null +++ b/packages/subgraph/src/simple-loan-elastic-proposal.ts @@ -0,0 +1,44 @@ +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" +import { SimpleLoanElasticProposalProposalMade } from "../generated/schema" + +export function handleProposalMade(event: ProposalMadeEvent): void { + const entity = new SimpleLoanElasticProposalProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.proposalHash = event.params.proposalHash + entity.proposer = event.params.proposer + entity.proposal_collateralCategory = event.params.proposal.collateralCategory + entity.proposal_collateralAddress = event.params.proposal.collateralAddress + entity.proposal_collateralId = event.params.proposal.collateralId + entity.proposal_checkCollateralStateFingerprint = + event.params.proposal.checkCollateralStateFingerprint + entity.proposal_collateralStateFingerprint = + event.params.proposal.collateralStateFingerprint + entity.proposal_creditAddress = event.params.proposal.creditAddress + entity.proposal_creditPerCollateralUnit = + event.params.proposal.creditPerCollateralUnit + entity.proposal_minCreditAmount = event.params.proposal.minCreditAmount + entity.proposal_availableCreditLimit = + event.params.proposal.availableCreditLimit + entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId + entity.proposal_fixedInterestAmount = + event.params.proposal.fixedInterestAmount + entity.proposal_accruingInterestAPR = + event.params.proposal.accruingInterestAPR + entity.proposal_durationOrDate = event.params.proposal.durationOrDate + entity.proposal_expiration = event.params.proposal.expiration + entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor + entity.proposal_proposer = event.params.proposal.proposer + entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash + entity.proposal_isOffer = event.params.proposal.isOffer + entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId + entity.proposal_nonceSpace = event.params.proposal.nonceSpace + entity.proposal_nonce = event.params.proposal.nonce + entity.proposal_loanContract = event.params.proposal.loanContract + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/simple-loan-list-proposal.ts b/packages/subgraph/src/simple-loan-list-proposal.ts new file mode 100644 index 00000000..871b3e84 --- /dev/null +++ b/packages/subgraph/src/simple-loan-list-proposal.ts @@ -0,0 +1,44 @@ +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" +import { SimpleLoanListProposalProposalMade } from "../generated/schema" + +export function handleProposalMade(event: ProposalMadeEvent): void { + const entity = new SimpleLoanListProposalProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.proposalHash = event.params.proposalHash + entity.proposer = event.params.proposer + entity.proposal_collateralCategory = event.params.proposal.collateralCategory + entity.proposal_collateralAddress = event.params.proposal.collateralAddress + entity.proposal_collateralIdsWhitelistMerkleRoot = + event.params.proposal.collateralIdsWhitelistMerkleRoot + entity.proposal_collateralAmount = event.params.proposal.collateralAmount + entity.proposal_checkCollateralStateFingerprint = + event.params.proposal.checkCollateralStateFingerprint + entity.proposal_collateralStateFingerprint = + event.params.proposal.collateralStateFingerprint + entity.proposal_creditAddress = event.params.proposal.creditAddress + entity.proposal_creditAmount = event.params.proposal.creditAmount + entity.proposal_availableCreditLimit = + event.params.proposal.availableCreditLimit + entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId + entity.proposal_fixedInterestAmount = + event.params.proposal.fixedInterestAmount + entity.proposal_accruingInterestAPR = + event.params.proposal.accruingInterestAPR + entity.proposal_durationOrDate = event.params.proposal.durationOrDate + entity.proposal_expiration = event.params.proposal.expiration + entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor + entity.proposal_proposer = event.params.proposal.proposer + entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash + entity.proposal_isOffer = event.params.proposal.isOffer + entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId + entity.proposal_nonceSpace = event.params.proposal.nonceSpace + entity.proposal_nonce = event.params.proposal.nonce + entity.proposal_loanContract = event.params.proposal.loanContract + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/simple-loan-simple-proposal.ts b/packages/subgraph/src/simple-loan-simple-proposal.ts new file mode 100644 index 00000000..a2210e37 --- /dev/null +++ b/packages/subgraph/src/simple-loan-simple-proposal.ts @@ -0,0 +1,43 @@ +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" +import { ProposalMade } from "../generated/schema" + +export function handleProposalMade(event: ProposalMadeEvent): void { + const entity = new ProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.proposalHash = event.params.proposalHash + entity.proposer = event.params.proposer + entity.proposal_collateralCategory = event.params.proposal.collateralCategory + entity.proposal_collateralAddress = event.params.proposal.collateralAddress + entity.proposal_collateralId = event.params.proposal.collateralId + entity.proposal_collateralAmount = event.params.proposal.collateralAmount + entity.proposal_checkCollateralStateFingerprint = + event.params.proposal.checkCollateralStateFingerprint + entity.proposal_collateralStateFingerprint = + event.params.proposal.collateralStateFingerprint + entity.proposal_creditAddress = event.params.proposal.creditAddress + entity.proposal_creditAmount = event.params.proposal.creditAmount + entity.proposal_availableCreditLimit = + event.params.proposal.availableCreditLimit + entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId + entity.proposal_fixedInterestAmount = + event.params.proposal.fixedInterestAmount + entity.proposal_accruingInterestAPR = + event.params.proposal.accruingInterestAPR + entity.proposal_durationOrDate = event.params.proposal.durationOrDate + entity.proposal_expiration = event.params.proposal.expiration + entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor + entity.proposal_proposer = event.params.proposal.proposer + entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash + entity.proposal_isOffer = event.params.proposal.isOffer + entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId + entity.proposal_nonceSpace = event.params.proposal.nonceSpace + entity.proposal_nonce = event.params.proposal.nonce + entity.proposal_loanContract = event.params.proposal.loanContract + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/src/simple-loan.ts b/packages/subgraph/src/simple-loan.ts new file mode 100644 index 00000000..cfc8989a --- /dev/null +++ b/packages/subgraph/src/simple-loan.ts @@ -0,0 +1,215 @@ +import { + ExtensionProposalMade as ExtensionProposalMadeEvent, + LOANClaimed as LOANClaimedEvent, + LOANCreated as LOANCreatedEvent, + LOANExtended as LOANExtendedEvent, + LOANPaidBack as LOANPaidBackEvent, + PoolSupply as PoolSupplyEvent, + PoolWithdraw as PoolWithdrawEvent, + VaultPull as VaultPullEvent, + VaultPush as VaultPushEvent, + VaultPushFrom as VaultPushFromEvent, +} from "../generated/SimpleLoan/SimpleLoan" +import { + ExtensionProposalMade, + LOANClaimed, + LOANCreated, + LOANExtended, + LOANPaidBack, + PoolSupply, + PoolWithdraw, + VaultPull, + VaultPush, + VaultPushFrom, +} from "../generated/schema" + +export function handleExtensionProposalMade( + event: ExtensionProposalMadeEvent, +): void { + const entity = new ExtensionProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.extensionHash = event.params.extensionHash + entity.proposer = event.params.proposer + entity.proposal_loanId = event.params.proposal.loanId + entity.proposal_compensationAddress = + event.params.proposal.compensationAddress + entity.proposal_compensationAmount = event.params.proposal.compensationAmount + entity.proposal_duration = event.params.proposal.duration + entity.proposal_expiration = event.params.proposal.expiration + entity.proposal_proposer = event.params.proposal.proposer + entity.proposal_nonceSpace = event.params.proposal.nonceSpace + entity.proposal_nonce = event.params.proposal.nonce + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANClaimed(event: LOANClaimedEvent): void { + const entity = new LOANClaimed( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanId = event.params.loanId + entity.defaulted = event.params.defaulted + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANCreated(event: LOANCreatedEvent): void { + const entity = new LOANCreated( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanId = event.params.loanId + entity.proposalHash = event.params.proposalHash + entity.proposalContract = event.params.proposalContract + entity.refinancingLoanId = event.params.refinancingLoanId + entity.terms_lender = event.params.terms.lender + entity.terms_borrower = event.params.terms.borrower + entity.terms_duration = event.params.terms.duration + entity.terms_collateral_category = event.params.terms.collateral.category + entity.terms_collateral_assetAddress = + event.params.terms.collateral.assetAddress + entity.terms_collateral_id = event.params.terms.collateral.id + entity.terms_collateral_amount = event.params.terms.collateral.amount + entity.terms_credit_category = event.params.terms.credit.category + entity.terms_credit_assetAddress = event.params.terms.credit.assetAddress + entity.terms_credit_id = event.params.terms.credit.id + entity.terms_credit_amount = event.params.terms.credit.amount + entity.terms_fixedInterestAmount = event.params.terms.fixedInterestAmount + entity.terms_accruingInterestAPR = event.params.terms.accruingInterestAPR + entity.terms_lenderSpecHash = event.params.terms.lenderSpecHash + entity.terms_borrowerSpecHash = event.params.terms.borrowerSpecHash + entity.lenderSpec_sourceOfFunds = event.params.lenderSpec.sourceOfFunds + entity.extra = event.params.extra + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANExtended(event: LOANExtendedEvent): void { + const entity = new LOANExtended( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanId = event.params.loanId + entity.originalDefaultTimestamp = event.params.originalDefaultTimestamp + entity.extendedDefaultTimestamp = event.params.extendedDefaultTimestamp + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleLOANPaidBack(event: LOANPaidBackEvent): void { + const entity = new LOANPaidBack( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.loanId = event.params.loanId + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handlePoolSupply(event: PoolSupplyEvent): void { + const entity = new PoolSupply( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset_category = event.params.asset.category + entity.asset_assetAddress = event.params.asset.assetAddress + entity.asset_id = event.params.asset.id + entity.asset_amount = event.params.asset.amount + entity.poolAdapter = event.params.poolAdapter + entity.pool = event.params.pool + entity.owner = event.params.owner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handlePoolWithdraw(event: PoolWithdrawEvent): void { + const entity = new PoolWithdraw( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset_category = event.params.asset.category + entity.asset_assetAddress = event.params.asset.assetAddress + entity.asset_id = event.params.asset.id + entity.asset_amount = event.params.asset.amount + entity.poolAdapter = event.params.poolAdapter + entity.pool = event.params.pool + entity.owner = event.params.owner + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleVaultPull(event: VaultPullEvent): void { + const entity = new VaultPull( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset_category = event.params.asset.category + entity.asset_assetAddress = event.params.asset.assetAddress + entity.asset_id = event.params.asset.id + entity.asset_amount = event.params.asset.amount + entity.origin = event.params.origin + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleVaultPush(event: VaultPushEvent): void { + const entity = new VaultPush( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset_category = event.params.asset.category + entity.asset_assetAddress = event.params.asset.assetAddress + entity.asset_id = event.params.asset.id + entity.asset_amount = event.params.asset.amount + entity.beneficiary = event.params.beneficiary + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} + +export function handleVaultPushFrom(event: VaultPushFromEvent): void { + const entity = new VaultPushFrom( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + entity.asset_category = event.params.asset.category + entity.asset_assetAddress = event.params.asset.assetAddress + entity.asset_id = event.params.asset.id + entity.asset_amount = event.params.asset.amount + entity.origin = event.params.origin + entity.beneficiary = event.params.beneficiary + + entity.blockNumber = event.block.number + entity.blockTimestamp = event.block.timestamp + entity.transactionHash = event.transaction.hash + + entity.save() +} diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index e92b4d95..a05644b8 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -2,27 +2,315 @@ specVersion: 0.0.5 schema: file: ./schema.graphql dataSources: - # Simple Loan Contract - - kind: ethereum/contract - name: PWN_SimpleLoan + # TODO should we also include: + # - RevokedNonce ? + # - Config? + # - Hub? + # - SimpleLoanDutchAuction? + + # TODO go over the events here and see what we can remove + - kind: ethereum + name: SimpleLoanSimpleProposal network: {{network}} source: - address: "{{SimpleLoanAddress}}" + address: "{{SimpleLoanSimpleProposal.address}}" + abi: SimpleLoanSimpleProposal + startBlock: {{SimpleLoanSimpleProposal.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - ProposalMade + abis: + - name: SimpleLoanSimpleProposal + file: ./abis/SimpleLoanSimpleProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-simple-proposal.ts + - kind: ethereum + name: SimpleLoanListProposal + network: {{network}} + source: + address: "{{SimpleLoanListProposal.address}}" + abi: SimpleLoanListProposal + startBlock: {{SimpleLoanListProposal.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanListProposalProposalMade + abis: + - name: SimpleLoanListProposal + file: ./abis/SimpleLoanListProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,bytes32,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-list-proposal.ts + - kind: ethereum + name: SimpleLoanElasticProposal + network: {{network}} + source: + address: "{{SimpleLoanElasticProposal.address}}" + abi: SimpleLoanElasticProposal + startBlock: {{SimpleLoanElasticProposal.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanElasticProposalProposalMade + abis: + - name: SimpleLoanElasticProposal + file: ./abis/SimpleLoanElasticProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,uint256,bool,bytes32,address,uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-elastic-proposal.ts + - kind: ethereum + name: SimpleLoanElasticChainlinkProposal + network: {{network}} + source: + address: "{{SimpleLoanElasticChainlinkProposal.address}}" + abi: SimpleLoanElasticChainlinkProposal + startBlock: {{SimpleLoanElasticChainlinkProposal.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanElasticChainlinkProposalProposalMade + abis: + - name: SimpleLoanElasticChainlinkProposal + file: ./abis/SimpleLoanElasticChainlinkProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,uint256,bool,bytes32,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-elastic-chainlink-proposal.ts + - kind: ethereum + name: SimpleLoan + network: {{network}} + source: + address: "{{SimpleLoan.address}}" abi: SimpleLoan - startBlock: {{SimpleLoanStartBlock}} + startBlock: {{SimpleLoan.startBlock}} mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.9 language: wasm/assemblyscript - entities: [ Loan, Account ] + entities: + - ExtensionProposalMade + - LOANClaimed + - LOANCreated + - LOANExtended + - LOANPaidBack + - PoolSupply + - PoolWithdraw + - VaultPull + - VaultPush + - VaultPushFrom abis: - name: SimpleLoan file: ./abis/SimpleLoan.json eventHandlers: - - event: LOANCreated(indexed uint256,indexed bytes32,indexed address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) + - event: ExtensionProposalMade(indexed bytes32,indexed + address,(uint256,address,uint256,uint40,uint40,address,uint256,uint256)) + handler: handleExtensionProposalMade + - event: LOANClaimed(indexed uint256,indexed bool) + handler: handleLOANClaimed + - event: LOANCreated(indexed uint256,indexed bytes32,indexed + address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) handler: handleLOANCreated + - event: LOANExtended(indexed uint256,uint40,uint40) + handler: handleLOANExtended - event: LOANPaidBack(indexed uint256) handler: handleLOANPaidBack - - event: LOANClaimed(indexed uint256,indexed bool) - handler: handleLOANClaimed - file: ./src/loan-mapping.ts + - event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed + address) + handler: handlePoolSupply + - event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed + address,indexed address) + handler: handlePoolWithdraw + - event: VaultPull((uint8,address,uint256,uint256),indexed address) + handler: handleVaultPull + - event: VaultPush((uint8,address,uint256,uint256),indexed address) + handler: handleVaultPush + - event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) + handler: handleVaultPushFrom + file: ./src/simple-loan.ts + - kind: ethereum + name: LoanToken + network: {{network}} + source: + address: "{{LoanToken.address}}" + abi: LoanToken + startBlock: {{LoanToken.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - Approval + - ApprovalForAll + - LOANBurned + - LOANMinted + - Transfer + abis: + - name: LoanToken + file: ./abis/LoanToken.json + eventHandlers: + - event: Approval(indexed address,indexed address,indexed uint256) + handler: handleApproval + - event: ApprovalForAll(indexed address,indexed address,bool) + handler: handleApprovalForAll + - event: LOANBurned(indexed uint256) + handler: handleLOANBurned + - event: LOANMinted(indexed uint256,indexed address,indexed address) + handler: handleLOANMinted + - event: Transfer(indexed address,indexed address,indexed uint256) + handler: handleTransfer + file: ./src/loan-token.ts + # TODO update Config abi + # TODO should we also have proxy upgrade events in the config address? + - kind: ethereum + name: Config + network: {{network}} + source: + address: "{{Config.address}}" + abi: Config + startBlock: {{Config.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - AdminChanged + - BeaconUpgraded + - Upgraded + - DefaultLOANMetadataUriUpdated + - FeeCollectorUpdated + - FeeUpdated + - Initialized + - LOANMetadataUriUpdated + - ConfigOwnershipTransferStarted + - ConfigOwnershipTransferred + abis: + - name: Config + file: ./abis/Config.json + eventHandlers: + - event: AdminChanged(address,address) + handler: handleAdminChanged + - event: BeaconUpgraded(indexed address) + handler: handleBeaconUpgraded + - event: Upgraded(indexed address) + handler: handleUpgraded + - event: DefaultLOANMetadataUriUpdated(string) + handler: handleDefaultLOANMetadataUriUpdated + - event: FeeCollectorUpdated(address,address) + handler: handleFeeCollectorUpdated + - event: FeeUpdated(uint16,uint16) + handler: handleFeeUpdated + - event: Initialized(uint8) + handler: handleInitialized + - event: LOANMetadataUriUpdated(indexed address,string) + handler: handleLOANMetadataUriUpdated + - event: OwnershipTransferStarted(indexed address,indexed address) + handler: handleOwnershipTransferStarted + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + file: ./src/config.ts + - kind: ethereum + name: Hub + network: {{network}} + source: + address: "{{Hub.address}}" + abi: Hub + startBlock: {{Hub.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - OwnershipTransferStarted + - OwnershipTransferred + - TagSet + abis: + - name: Hub + file: ./abis/Hub.json + eventHandlers: + - event: OwnershipTransferStarted(indexed address,indexed address) + handler: handleOwnershipTransferStarted + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + - event: TagSet(indexed address,indexed bytes32,bool) + handler: handleTagSet + file: ./src/hub.ts + - kind: ethereum + name: ChainlinkFeedRegistry + network: {{network}} + source: + address: "{{ChainlinkFeedRegistry.address}}" + abi: ChainlinkFeedRegistry + startBlock: {{ChainlinkFeedRegistry.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - AccessControllerSet + - FeedConfirmed + - FeedProposed + - OwnershipTransferRequested + - ChainlinkFeedRegistryOwnershipTransferred + abis: + - name: ChainlinkFeedRegistry + file: ./abis/ChainlinkFeedRegistry.json + eventHandlers: + - event: AccessControllerSet(indexed address,indexed address) + handler: handleAccessControllerSet + - event: FeedConfirmed(indexed address,indexed address,indexed + address,address,uint16,address) + handler: handleFeedConfirmed + - event: FeedProposed(indexed address,indexed address,indexed address,address,address) + handler: handleFeedProposed + - event: OwnershipTransferRequested(indexed address,indexed address) + handler: handleOwnershipTransferRequested + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + file: ./src/chainlink-feed-registry.ts + - kind: ethereum + name: MultiTokenCategoryRegistry + network: {{network}} + source: + address: "{{MultiTokenCategoryRegistry.address}}" + abi: MultiTokenCategoryRegistry + startBlock: {{MultiTokenCategoryRegistry.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - CategoryRegistered + - CategoryUnregistered + - MultiTokenCategoryRegistryOwnershipTransferStarted + - MultiTokenCategoryRegistryOwnershipTransferred + abis: + - name: MultiTokenCategoryRegistry + file: ./abis/MultiTokenCategoryRegistry.json + eventHandlers: + - event: CategoryRegistered(indexed address,indexed uint8) + handler: handleCategoryRegistered + - event: CategoryUnregistered(indexed address) + handler: handleCategoryUnregistered + - event: OwnershipTransferStarted(indexed address,indexed address) + handler: handleOwnershipTransferStarted + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + file: ./src/multi-token-category-registry.ts + diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index bda233ac..17d0b47d 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -2,9 +2,99 @@ specVersion: 0.0.5 schema: file: ./schema.graphql dataSources: - # Simple Loan Contract - - kind: ethereum/contract - name: PWN_SimpleLoan + # TODO should we also include: + # - RevokedNonce ? + # - Config? + # - Hub? + # - SimpleLoanDutchAuction? + + # TODO go over the events here and see what we can remove + - kind: ethereum + name: SimpleLoanSimpleProposal + network: sepolia + source: + address: "0xe624E7D33baC728bE2bdB606Da0018B6E05A84D9" + abi: SimpleLoanSimpleProposal + startBlock: 7298850 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - ProposalMade + abis: + - name: SimpleLoanSimpleProposal + file: ./abis/SimpleLoanSimpleProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-simple-proposal.ts + - kind: ethereum + name: SimpleLoanListProposal + network: sepolia + source: + address: "0x7160Ec33788Df9AFb8AAEe777e7Ae21151B51eDd" + abi: SimpleLoanListProposal + startBlock: 7298850 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanListProposalProposalMade + abis: + - name: SimpleLoanListProposal + file: ./abis/SimpleLoanListProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,bytes32,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-list-proposal.ts + - kind: ethereum + name: SimpleLoanElasticProposal + network: sepolia + source: + address: "0xeC6390D4B22FFfD22E5C5FDB56DaF653C3Cd0626" + abi: SimpleLoanElasticProposal + startBlock: 7298851 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanElasticProposalProposalMade + abis: + - name: SimpleLoanElasticProposal + file: ./abis/SimpleLoanElasticProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,uint256,bool,bytes32,address,uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-elastic-proposal.ts + - kind: ethereum + name: SimpleLoanElasticChainlinkProposal + network: sepolia + source: + address: "0xC46170F43b97faE1A8B507d6fdDaFfBb7527D61B" + abi: SimpleLoanElasticChainlinkProposal + startBlock: 8069855 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanElasticChainlinkProposalProposalMade + abis: + - name: SimpleLoanElasticChainlinkProposal + file: ./abis/SimpleLoanElasticChainlinkProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint8,address,uint256,bool,bytes32,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-elastic-chainlink-proposal.ts + - kind: ethereum + name: SimpleLoan network: sepolia source: address: "0x719A69d0dc67bd3Aa7648D4694081B3c87952797" @@ -12,17 +102,215 @@ dataSources: startBlock: 7298850 mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.9 language: wasm/assemblyscript - entities: [ Loan, Account ] + entities: + - ExtensionProposalMade + - LOANClaimed + - LOANCreated + - LOANExtended + - LOANPaidBack + - PoolSupply + - PoolWithdraw + - VaultPull + - VaultPush + - VaultPushFrom abis: - name: SimpleLoan file: ./abis/SimpleLoan.json eventHandlers: - - event: LOANCreated(indexed uint256,indexed bytes32,indexed address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) + - event: ExtensionProposalMade(indexed bytes32,indexed + address,(uint256,address,uint256,uint40,uint40,address,uint256,uint256)) + handler: handleExtensionProposalMade + - event: LOANClaimed(indexed uint256,indexed bool) + handler: handleLOANClaimed + - event: LOANCreated(indexed uint256,indexed bytes32,indexed + address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) handler: handleLOANCreated + - event: LOANExtended(indexed uint256,uint40,uint40) + handler: handleLOANExtended - event: LOANPaidBack(indexed uint256) handler: handleLOANPaidBack - - event: LOANClaimed(indexed uint256,indexed bool) - handler: handleLOANClaimed - file: ./src/loan-mapping.ts + - event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed + address) + handler: handlePoolSupply + - event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed + address,indexed address) + handler: handlePoolWithdraw + - event: VaultPull((uint8,address,uint256,uint256),indexed address) + handler: handleVaultPull + - event: VaultPush((uint8,address,uint256,uint256),indexed address) + handler: handleVaultPush + - event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) + handler: handleVaultPushFrom + file: ./src/simple-loan.ts + - kind: ethereum + name: LoanToken + network: sepolia + source: + address: "0x4440C069272cC34b80C7B11bEE657D0349Ba9C23" + abi: LoanToken + startBlock: 4435806 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - Approval + - ApprovalForAll + - LOANBurned + - LOANMinted + - Transfer + abis: + - name: LoanToken + file: ./abis/LoanToken.json + eventHandlers: + - event: Approval(indexed address,indexed address,indexed uint256) + handler: handleApproval + - event: ApprovalForAll(indexed address,indexed address,bool) + handler: handleApprovalForAll + - event: LOANBurned(indexed uint256) + handler: handleLOANBurned + - event: LOANMinted(indexed uint256,indexed address,indexed address) + handler: handleLOANMinted + - event: Transfer(indexed address,indexed address,indexed uint256) + handler: handleTransfer + file: ./src/loan-token.ts + # TODO update Config abi + # TODO should we also have proxy upgrade events in the config address? + - kind: ethereum + name: Config + network: sepolia + source: + address: "0xd52a2898d61636bB3eEF0d145f05352FF543bdCC" + abi: Config + startBlock: 5953668 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - AdminChanged + - BeaconUpgraded + - Upgraded + - DefaultLOANMetadataUriUpdated + - FeeCollectorUpdated + - FeeUpdated + - Initialized + - LOANMetadataUriUpdated + - ConfigOwnershipTransferStarted + - ConfigOwnershipTransferred + abis: + - name: Config + file: ./abis/Config.json + eventHandlers: + - event: AdminChanged(address,address) + handler: handleAdminChanged + - event: BeaconUpgraded(indexed address) + handler: handleBeaconUpgraded + - event: Upgraded(indexed address) + handler: handleUpgraded + - event: DefaultLOANMetadataUriUpdated(string) + handler: handleDefaultLOANMetadataUriUpdated + - event: FeeCollectorUpdated(address,address) + handler: handleFeeCollectorUpdated + - event: FeeUpdated(uint16,uint16) + handler: handleFeeUpdated + - event: Initialized(uint8) + handler: handleInitialized + - event: LOANMetadataUriUpdated(indexed address,string) + handler: handleLOANMetadataUriUpdated + - event: OwnershipTransferStarted(indexed address,indexed address) + handler: handleOwnershipTransferStarted + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + file: ./src/config.ts + - kind: ethereum + name: Hub + network: sepolia + source: + address: "0x37807A2F031b3B44081F4b21500E5D70EbaDAdd5" + abi: Hub + startBlock: 4435806 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - OwnershipTransferStarted + - OwnershipTransferred + - TagSet + abis: + - name: Hub + file: ./abis/Hub.json + eventHandlers: + - event: OwnershipTransferStarted(indexed address,indexed address) + handler: handleOwnershipTransferStarted + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + - event: TagSet(indexed address,indexed bytes32,bool) + handler: handleTagSet + file: ./src/hub.ts + - kind: ethereum + name: ChainlinkFeedRegistry + network: sepolia + source: + address: "0x8D5e90706E52a52853dA9A14fA1c63889a412851" + abi: ChainlinkFeedRegistry + startBlock: 7298850 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - AccessControllerSet + - FeedConfirmed + - FeedProposed + - OwnershipTransferRequested + - ChainlinkFeedRegistryOwnershipTransferred + abis: + - name: ChainlinkFeedRegistry + file: ./abis/ChainlinkFeedRegistry.json + eventHandlers: + - event: AccessControllerSet(indexed address,indexed address) + handler: handleAccessControllerSet + - event: FeedConfirmed(indexed address,indexed address,indexed + address,address,uint16,address) + handler: handleFeedConfirmed + - event: FeedProposed(indexed address,indexed address,indexed address,address,address) + handler: handleFeedProposed + - event: OwnershipTransferRequested(indexed address,indexed address) + handler: handleOwnershipTransferRequested + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + file: ./src/chainlink-feed-registry.ts + - kind: ethereum + name: MultiTokenCategoryRegistry + network: sepolia + source: + address: "0xbB2168d5546A94AE2DA9254e63D88F7f137B2534" + abi: MultiTokenCategoryRegistry + startBlock: 5953672 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - CategoryRegistered + - CategoryUnregistered + - MultiTokenCategoryRegistryOwnershipTransferStarted + - MultiTokenCategoryRegistryOwnershipTransferred + abis: + - name: MultiTokenCategoryRegistry + file: ./abis/MultiTokenCategoryRegistry.json + eventHandlers: + - event: CategoryRegistered(indexed address,indexed uint8) + handler: handleCategoryRegistered + - event: CategoryUnregistered(indexed address) + handler: handleCategoryUnregistered + - event: OwnershipTransferStarted(indexed address,indexed address) + handler: handleOwnershipTransferStarted + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred + file: ./src/multi-token-category-registry.ts + diff --git a/packages/subgraph/tests/chainlink-feed-registry-utils.ts b/packages/subgraph/tests/chainlink-feed-registry-utils.ts new file mode 100644 index 00000000..6e6aa1fa --- /dev/null +++ b/packages/subgraph/tests/chainlink-feed-registry-utils.ts @@ -0,0 +1,153 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Address } from "@graphprotocol/graph-ts" +import { + AccessControllerSet, + FeedConfirmed, + FeedProposed, + OwnershipTransferRequested, + OwnershipTransferred +} from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" + +export function createAccessControllerSetEvent( + accessController: Address, + sender: Address +): AccessControllerSet { + let accessControllerSetEvent = changetype(newMockEvent()) + + accessControllerSetEvent.parameters = new Array() + + accessControllerSetEvent.parameters.push( + new ethereum.EventParam( + "accessController", + ethereum.Value.fromAddress(accessController) + ) + ) + accessControllerSetEvent.parameters.push( + new ethereum.EventParam("sender", ethereum.Value.fromAddress(sender)) + ) + + return accessControllerSetEvent +} + +export function createFeedConfirmedEvent( + asset: Address, + denomination: Address, + latestAggregator: Address, + previousAggregator: Address, + nextPhaseId: i32, + sender: Address +): FeedConfirmed { + let feedConfirmedEvent = changetype(newMockEvent()) + + feedConfirmedEvent.parameters = new Array() + + feedConfirmedEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromAddress(asset)) + ) + feedConfirmedEvent.parameters.push( + new ethereum.EventParam( + "denomination", + ethereum.Value.fromAddress(denomination) + ) + ) + feedConfirmedEvent.parameters.push( + new ethereum.EventParam( + "latestAggregator", + ethereum.Value.fromAddress(latestAggregator) + ) + ) + feedConfirmedEvent.parameters.push( + new ethereum.EventParam( + "previousAggregator", + ethereum.Value.fromAddress(previousAggregator) + ) + ) + feedConfirmedEvent.parameters.push( + new ethereum.EventParam( + "nextPhaseId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(nextPhaseId)) + ) + ) + feedConfirmedEvent.parameters.push( + new ethereum.EventParam("sender", ethereum.Value.fromAddress(sender)) + ) + + return feedConfirmedEvent +} + +export function createFeedProposedEvent( + asset: Address, + denomination: Address, + proposedAggregator: Address, + currentAggregator: Address, + sender: Address +): FeedProposed { + let feedProposedEvent = changetype(newMockEvent()) + + feedProposedEvent.parameters = new Array() + + feedProposedEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromAddress(asset)) + ) + feedProposedEvent.parameters.push( + new ethereum.EventParam( + "denomination", + ethereum.Value.fromAddress(denomination) + ) + ) + feedProposedEvent.parameters.push( + new ethereum.EventParam( + "proposedAggregator", + ethereum.Value.fromAddress(proposedAggregator) + ) + ) + feedProposedEvent.parameters.push( + new ethereum.EventParam( + "currentAggregator", + ethereum.Value.fromAddress(currentAggregator) + ) + ) + feedProposedEvent.parameters.push( + new ethereum.EventParam("sender", ethereum.Value.fromAddress(sender)) + ) + + return feedProposedEvent +} + +export function createOwnershipTransferRequestedEvent( + from: Address, + to: Address +): OwnershipTransferRequested { + let ownershipTransferRequestedEvent = + changetype(newMockEvent()) + + ownershipTransferRequestedEvent.parameters = new Array() + + ownershipTransferRequestedEvent.parameters.push( + new ethereum.EventParam("from", ethereum.Value.fromAddress(from)) + ) + ownershipTransferRequestedEvent.parameters.push( + new ethereum.EventParam("to", ethereum.Value.fromAddress(to)) + ) + + return ownershipTransferRequestedEvent +} + +export function createOwnershipTransferredEvent( + from: Address, + to: Address +): OwnershipTransferred { + let ownershipTransferredEvent = + changetype(newMockEvent()) + + ownershipTransferredEvent.parameters = new Array() + + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam("from", ethereum.Value.fromAddress(from)) + ) + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam("to", ethereum.Value.fromAddress(to)) + ) + + return ownershipTransferredEvent +} diff --git a/packages/subgraph/tests/chainlink-feed-registry.test.ts b/packages/subgraph/tests/chainlink-feed-registry.test.ts new file mode 100644 index 00000000..59757679 --- /dev/null +++ b/packages/subgraph/tests/chainlink-feed-registry.test.ts @@ -0,0 +1,60 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Address } from "@graphprotocol/graph-ts" +import { AccessControllerSet } from "../generated/schema" +import { AccessControllerSet as AccessControllerSetEvent } from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" +import { handleAccessControllerSet } from "../src/chainlink-feed-registry" +import { createAccessControllerSetEvent } from "./chainlink-feed-registry-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let accessController = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let sender = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let newAccessControllerSetEvent = createAccessControllerSetEvent( + accessController, + sender + ) + handleAccessControllerSet(newAccessControllerSetEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("AccessControllerSet created and stored", () => { + assert.entityCount("AccessControllerSet", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "AccessControllerSet", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "accessController", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "AccessControllerSet", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "sender", + "0x0000000000000000000000000000000000000001" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/config-utils.ts b/packages/subgraph/tests/config-utils.ts new file mode 100644 index 00000000..3241e3c0 --- /dev/null +++ b/packages/subgraph/tests/config-utils.ts @@ -0,0 +1,203 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Address } from "@graphprotocol/graph-ts" +import { + AdminChanged, + BeaconUpgraded, + Upgraded, + DefaultLOANMetadataUriUpdated, + FeeCollectorUpdated, + FeeUpdated, + Initialized, + LOANMetadataUriUpdated, + OwnershipTransferStarted, + OwnershipTransferred +} from "../generated/Config/Config" + +export function createAdminChangedEvent( + previousAdmin: Address, + newAdmin: Address +): AdminChanged { + let adminChangedEvent = changetype(newMockEvent()) + + adminChangedEvent.parameters = new Array() + + adminChangedEvent.parameters.push( + new ethereum.EventParam( + "previousAdmin", + ethereum.Value.fromAddress(previousAdmin) + ) + ) + adminChangedEvent.parameters.push( + new ethereum.EventParam("newAdmin", ethereum.Value.fromAddress(newAdmin)) + ) + + return adminChangedEvent +} + +export function createBeaconUpgradedEvent(beacon: Address): BeaconUpgraded { + let beaconUpgradedEvent = changetype(newMockEvent()) + + beaconUpgradedEvent.parameters = new Array() + + beaconUpgradedEvent.parameters.push( + new ethereum.EventParam("beacon", ethereum.Value.fromAddress(beacon)) + ) + + return beaconUpgradedEvent +} + +export function createUpgradedEvent(implementation: Address): Upgraded { + let upgradedEvent = changetype(newMockEvent()) + + upgradedEvent.parameters = new Array() + + upgradedEvent.parameters.push( + new ethereum.EventParam( + "implementation", + ethereum.Value.fromAddress(implementation) + ) + ) + + return upgradedEvent +} + +export function createDefaultLOANMetadataUriUpdatedEvent( + newUri: string +): DefaultLOANMetadataUriUpdated { + let defaultLoanMetadataUriUpdatedEvent = + changetype(newMockEvent()) + + defaultLoanMetadataUriUpdatedEvent.parameters = new Array() + + defaultLoanMetadataUriUpdatedEvent.parameters.push( + new ethereum.EventParam("newUri", ethereum.Value.fromString(newUri)) + ) + + return defaultLoanMetadataUriUpdatedEvent +} + +export function createFeeCollectorUpdatedEvent( + oldFeeCollector: Address, + newFeeCollector: Address +): FeeCollectorUpdated { + let feeCollectorUpdatedEvent = changetype(newMockEvent()) + + feeCollectorUpdatedEvent.parameters = new Array() + + feeCollectorUpdatedEvent.parameters.push( + new ethereum.EventParam( + "oldFeeCollector", + ethereum.Value.fromAddress(oldFeeCollector) + ) + ) + feeCollectorUpdatedEvent.parameters.push( + new ethereum.EventParam( + "newFeeCollector", + ethereum.Value.fromAddress(newFeeCollector) + ) + ) + + return feeCollectorUpdatedEvent +} + +export function createFeeUpdatedEvent(oldFee: i32, newFee: i32): FeeUpdated { + let feeUpdatedEvent = changetype(newMockEvent()) + + feeUpdatedEvent.parameters = new Array() + + feeUpdatedEvent.parameters.push( + new ethereum.EventParam( + "oldFee", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(oldFee)) + ) + ) + feeUpdatedEvent.parameters.push( + new ethereum.EventParam( + "newFee", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(newFee)) + ) + ) + + return feeUpdatedEvent +} + +export function createInitializedEvent(version: i32): Initialized { + let initializedEvent = changetype(newMockEvent()) + + initializedEvent.parameters = new Array() + + initializedEvent.parameters.push( + new ethereum.EventParam( + "version", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(version)) + ) + ) + + return initializedEvent +} + +export function createLOANMetadataUriUpdatedEvent( + loanContract: Address, + newUri: string +): LOANMetadataUriUpdated { + let loanMetadataUriUpdatedEvent = + changetype(newMockEvent()) + + loanMetadataUriUpdatedEvent.parameters = new Array() + + loanMetadataUriUpdatedEvent.parameters.push( + new ethereum.EventParam( + "loanContract", + ethereum.Value.fromAddress(loanContract) + ) + ) + loanMetadataUriUpdatedEvent.parameters.push( + new ethereum.EventParam("newUri", ethereum.Value.fromString(newUri)) + ) + + return loanMetadataUriUpdatedEvent +} + +export function createOwnershipTransferStartedEvent( + previousOwner: Address, + newOwner: Address +): OwnershipTransferStarted { + let ownershipTransferStartedEvent = + changetype(newMockEvent()) + + ownershipTransferStartedEvent.parameters = new Array() + + ownershipTransferStartedEvent.parameters.push( + new ethereum.EventParam( + "previousOwner", + ethereum.Value.fromAddress(previousOwner) + ) + ) + ownershipTransferStartedEvent.parameters.push( + new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) + ) + + return ownershipTransferStartedEvent +} + +export function createOwnershipTransferredEvent( + previousOwner: Address, + newOwner: Address +): OwnershipTransferred { + let ownershipTransferredEvent = + changetype(newMockEvent()) + + ownershipTransferredEvent.parameters = new Array() + + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam( + "previousOwner", + ethereum.Value.fromAddress(previousOwner) + ) + ) + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) + ) + + return ownershipTransferredEvent +} diff --git a/packages/subgraph/tests/config.test.ts b/packages/subgraph/tests/config.test.ts new file mode 100644 index 00000000..90e2beb9 --- /dev/null +++ b/packages/subgraph/tests/config.test.ts @@ -0,0 +1,57 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Address } from "@graphprotocol/graph-ts" +import { AdminChanged } from "../generated/schema" +import { AdminChanged as AdminChangedEvent } from "../generated/Config/Config" +import { handleAdminChanged } from "../src/config" +import { createAdminChangedEvent } from "./config-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let previousAdmin = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let newAdmin = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let newAdminChangedEvent = createAdminChangedEvent(previousAdmin, newAdmin) + handleAdminChanged(newAdminChangedEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("AdminChanged created and stored", () => { + assert.entityCount("AdminChanged", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "AdminChanged", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "previousAdmin", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "AdminChanged", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "newAdmin", + "0x0000000000000000000000000000000000000001" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/hub-utils.ts b/packages/subgraph/tests/hub-utils.ts new file mode 100644 index 00000000..c618cf7d --- /dev/null +++ b/packages/subgraph/tests/hub-utils.ts @@ -0,0 +1,73 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Address, Bytes } from "@graphprotocol/graph-ts" +import { + OwnershipTransferStarted, + OwnershipTransferred, + TagSet +} from "../generated/Hub/Hub" + +export function createOwnershipTransferStartedEvent( + previousOwner: Address, + newOwner: Address +): OwnershipTransferStarted { + let ownershipTransferStartedEvent = + changetype(newMockEvent()) + + ownershipTransferStartedEvent.parameters = new Array() + + ownershipTransferStartedEvent.parameters.push( + new ethereum.EventParam( + "previousOwner", + ethereum.Value.fromAddress(previousOwner) + ) + ) + ownershipTransferStartedEvent.parameters.push( + new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) + ) + + return ownershipTransferStartedEvent +} + +export function createOwnershipTransferredEvent( + previousOwner: Address, + newOwner: Address +): OwnershipTransferred { + let ownershipTransferredEvent = + changetype(newMockEvent()) + + ownershipTransferredEvent.parameters = new Array() + + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam( + "previousOwner", + ethereum.Value.fromAddress(previousOwner) + ) + ) + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) + ) + + return ownershipTransferredEvent +} + +export function createTagSetEvent( + _address: Address, + tag: Bytes, + hasTag: boolean +): TagSet { + let tagSetEvent = changetype(newMockEvent()) + + tagSetEvent.parameters = new Array() + + tagSetEvent.parameters.push( + new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address)) + ) + tagSetEvent.parameters.push( + new ethereum.EventParam("tag", ethereum.Value.fromFixedBytes(tag)) + ) + tagSetEvent.parameters.push( + new ethereum.EventParam("hasTag", ethereum.Value.fromBoolean(hasTag)) + ) + + return tagSetEvent +} diff --git a/packages/subgraph/tests/hub.test.ts b/packages/subgraph/tests/hub.test.ts new file mode 100644 index 00000000..221f5433 --- /dev/null +++ b/packages/subgraph/tests/hub.test.ts @@ -0,0 +1,60 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Address, Bytes } from "@graphprotocol/graph-ts" +import { OwnershipTransferStarted } from "../generated/schema" +import { OwnershipTransferStarted as OwnershipTransferStartedEvent } from "../generated/Hub/Hub" +import { handleOwnershipTransferStarted } from "../src/hub" +import { createOwnershipTransferStartedEvent } from "./hub-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let previousOwner = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let newOwner = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let newOwnershipTransferStartedEvent = createOwnershipTransferStartedEvent( + previousOwner, + newOwner + ) + handleOwnershipTransferStarted(newOwnershipTransferStartedEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("OwnershipTransferStarted created and stored", () => { + assert.entityCount("OwnershipTransferStarted", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "OwnershipTransferStarted", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "previousOwner", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "OwnershipTransferStarted", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "newOwner", + "0x0000000000000000000000000000000000000001" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/loan-token-utils.ts b/packages/subgraph/tests/loan-token-utils.ts new file mode 100644 index 00000000..489cf282 --- /dev/null +++ b/packages/subgraph/tests/loan-token-utils.ts @@ -0,0 +1,118 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Address, BigInt } from "@graphprotocol/graph-ts" +import { + Approval, + ApprovalForAll, + LOANBurned, + LOANMinted, + Transfer +} from "../generated/LoanToken/LoanToken" + +export function createApprovalEvent( + owner: Address, + approved: Address, + tokenId: BigInt +): Approval { + let approvalEvent = changetype(newMockEvent()) + + approvalEvent.parameters = new Array() + + approvalEvent.parameters.push( + new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + ) + approvalEvent.parameters.push( + new ethereum.EventParam("approved", ethereum.Value.fromAddress(approved)) + ) + approvalEvent.parameters.push( + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(tokenId) + ) + ) + + return approvalEvent +} + +export function createApprovalForAllEvent( + owner: Address, + operator: Address, + approved: boolean +): ApprovalForAll { + let approvalForAllEvent = changetype(newMockEvent()) + + approvalForAllEvent.parameters = new Array() + + approvalForAllEvent.parameters.push( + new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + ) + approvalForAllEvent.parameters.push( + new ethereum.EventParam("operator", ethereum.Value.fromAddress(operator)) + ) + approvalForAllEvent.parameters.push( + new ethereum.EventParam("approved", ethereum.Value.fromBoolean(approved)) + ) + + return approvalForAllEvent +} + +export function createLOANBurnedEvent(loanId: BigInt): LOANBurned { + let loanBurnedEvent = changetype(newMockEvent()) + + loanBurnedEvent.parameters = new Array() + + loanBurnedEvent.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) + ) + + return loanBurnedEvent +} + +export function createLOANMintedEvent( + loanId: BigInt, + loanContract: Address, + owner: Address +): LOANMinted { + let loanMintedEvent = changetype(newMockEvent()) + + loanMintedEvent.parameters = new Array() + + loanMintedEvent.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) + ) + loanMintedEvent.parameters.push( + new ethereum.EventParam( + "loanContract", + ethereum.Value.fromAddress(loanContract) + ) + ) + loanMintedEvent.parameters.push( + new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + ) + + return loanMintedEvent +} + +export function createTransferEvent( + from: Address, + to: Address, + tokenId: BigInt +): Transfer { + let transferEvent = changetype(newMockEvent()) + + transferEvent.parameters = new Array() + + transferEvent.parameters.push( + new ethereum.EventParam("from", ethereum.Value.fromAddress(from)) + ) + transferEvent.parameters.push( + new ethereum.EventParam("to", ethereum.Value.fromAddress(to)) + ) + transferEvent.parameters.push( + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(tokenId) + ) + ) + + return transferEvent +} diff --git a/packages/subgraph/tests/loan-token.test.ts b/packages/subgraph/tests/loan-token.test.ts new file mode 100644 index 00000000..c0596cd6 --- /dev/null +++ b/packages/subgraph/tests/loan-token.test.ts @@ -0,0 +1,62 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Address, BigInt } from "@graphprotocol/graph-ts" +import { Approval } from "../generated/schema" +import { Approval as ApprovalEvent } from "../generated/LoanToken/LoanToken" +import { handleApproval } from "../src/loan-token" +import { createApprovalEvent } from "./loan-token-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let owner = Address.fromString("0x0000000000000000000000000000000000000001") + let approved = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let tokenId = BigInt.fromI32(234) + let newApprovalEvent = createApprovalEvent(owner, approved, tokenId) + handleApproval(newApprovalEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("Approval created and stored", () => { + assert.entityCount("Approval", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "Approval", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "owner", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "Approval", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "approved", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "Approval", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "tokenId", + "234" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/multi-token-category-registry-utils.ts b/packages/subgraph/tests/multi-token-category-registry-utils.ts new file mode 100644 index 00000000..82206210 --- /dev/null +++ b/packages/subgraph/tests/multi-token-category-registry-utils.ts @@ -0,0 +1,94 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Address } from "@graphprotocol/graph-ts" +import { + CategoryRegistered, + CategoryUnregistered, + OwnershipTransferStarted, + OwnershipTransferred +} from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" + +export function createCategoryRegisteredEvent( + assetAddress: Address, + category: i32 +): CategoryRegistered { + let categoryRegisteredEvent = changetype(newMockEvent()) + + categoryRegisteredEvent.parameters = new Array() + + categoryRegisteredEvent.parameters.push( + new ethereum.EventParam( + "assetAddress", + ethereum.Value.fromAddress(assetAddress) + ) + ) + categoryRegisteredEvent.parameters.push( + new ethereum.EventParam( + "category", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(category)) + ) + ) + + return categoryRegisteredEvent +} + +export function createCategoryUnregisteredEvent( + assetAddress: Address +): CategoryUnregistered { + let categoryUnregisteredEvent = + changetype(newMockEvent()) + + categoryUnregisteredEvent.parameters = new Array() + + categoryUnregisteredEvent.parameters.push( + new ethereum.EventParam( + "assetAddress", + ethereum.Value.fromAddress(assetAddress) + ) + ) + + return categoryUnregisteredEvent +} + +export function createOwnershipTransferStartedEvent( + previousOwner: Address, + newOwner: Address +): OwnershipTransferStarted { + let ownershipTransferStartedEvent = + changetype(newMockEvent()) + + ownershipTransferStartedEvent.parameters = new Array() + + ownershipTransferStartedEvent.parameters.push( + new ethereum.EventParam( + "previousOwner", + ethereum.Value.fromAddress(previousOwner) + ) + ) + ownershipTransferStartedEvent.parameters.push( + new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) + ) + + return ownershipTransferStartedEvent +} + +export function createOwnershipTransferredEvent( + previousOwner: Address, + newOwner: Address +): OwnershipTransferred { + let ownershipTransferredEvent = + changetype(newMockEvent()) + + ownershipTransferredEvent.parameters = new Array() + + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam( + "previousOwner", + ethereum.Value.fromAddress(previousOwner) + ) + ) + ownershipTransferredEvent.parameters.push( + new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) + ) + + return ownershipTransferredEvent +} diff --git a/packages/subgraph/tests/multi-token-category-registry.test.ts b/packages/subgraph/tests/multi-token-category-registry.test.ts new file mode 100644 index 00000000..89533e16 --- /dev/null +++ b/packages/subgraph/tests/multi-token-category-registry.test.ts @@ -0,0 +1,58 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Address } from "@graphprotocol/graph-ts" +import { CategoryRegistered } from "../generated/schema" +import { CategoryRegistered as CategoryRegisteredEvent } from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" +import { handleCategoryRegistered } from "../src/multi-token-category-registry" +import { createCategoryRegisteredEvent } from "./multi-token-category-registry-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let assetAddress = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let category = 123 + let newCategoryRegisteredEvent = createCategoryRegisteredEvent( + assetAddress, + category + ) + handleCategoryRegistered(newCategoryRegisteredEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("CategoryRegistered created and stored", () => { + assert.entityCount("CategoryRegistered", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "CategoryRegistered", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "assetAddress", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "CategoryRegistered", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "category", + "123" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts b/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts new file mode 100644 index 00000000..249dd824 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts @@ -0,0 +1,28 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" + +export function createProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ProposalMade { + let proposalMadeEvent = changetype(newMockEvent()) + + proposalMadeEvent.parameters = new Array() + + proposalMadeEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return proposalMadeEvent +} diff --git a/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts b/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts new file mode 100644 index 00000000..cb88bb0b --- /dev/null +++ b/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/schema" +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" +import { handleProposalMade } from "../src/simple-loan-elastic-chainlink-proposal" +import { createProposalMadeEvent } from "./simple-loan-elastic-chainlink-proposal-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let proposalHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newProposalMadeEvent = createProposalMadeEvent( + proposalHash, + proposer, + proposal + ) + handleProposalMade(newProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ProposalMade created and stored", () => { + assert.entityCount("ProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposalHash", + "1234567890" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts b/packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts new file mode 100644 index 00000000..490f1cd3 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts @@ -0,0 +1,28 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" + +export function createProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ProposalMade { + let proposalMadeEvent = changetype(newMockEvent()) + + proposalMadeEvent.parameters = new Array() + + proposalMadeEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return proposalMadeEvent +} diff --git a/packages/subgraph/tests/simple-loan-elastic-proposal.test.ts b/packages/subgraph/tests/simple-loan-elastic-proposal.test.ts new file mode 100644 index 00000000..f872f535 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-elastic-proposal.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/schema" +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" +import { handleProposalMade } from "../src/simple-loan-elastic-proposal" +import { createProposalMadeEvent } from "./simple-loan-elastic-proposal-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let proposalHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newProposalMadeEvent = createProposalMadeEvent( + proposalHash, + proposer, + proposal + ) + handleProposalMade(newProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ProposalMade created and stored", () => { + assert.entityCount("ProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposalHash", + "1234567890" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/simple-loan-list-proposal-utils.ts b/packages/subgraph/tests/simple-loan-list-proposal-utils.ts new file mode 100644 index 00000000..94b71dde --- /dev/null +++ b/packages/subgraph/tests/simple-loan-list-proposal-utils.ts @@ -0,0 +1,28 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" + +export function createProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ProposalMade { + let proposalMadeEvent = changetype(newMockEvent()) + + proposalMadeEvent.parameters = new Array() + + proposalMadeEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return proposalMadeEvent +} diff --git a/packages/subgraph/tests/simple-loan-list-proposal.test.ts b/packages/subgraph/tests/simple-loan-list-proposal.test.ts new file mode 100644 index 00000000..853d7cfc --- /dev/null +++ b/packages/subgraph/tests/simple-loan-list-proposal.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/schema" +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" +import { handleProposalMade } from "../src/simple-loan-list-proposal" +import { createProposalMadeEvent } from "./simple-loan-list-proposal-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let proposalHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newProposalMadeEvent = createProposalMadeEvent( + proposalHash, + proposer, + proposal + ) + handleProposalMade(newProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ProposalMade created and stored", () => { + assert.entityCount("ProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposalHash", + "1234567890" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/simple-loan-simple-proposal-utils.ts b/packages/subgraph/tests/simple-loan-simple-proposal-utils.ts new file mode 100644 index 00000000..0b321ca2 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-simple-proposal-utils.ts @@ -0,0 +1,28 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" + +export function createProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ProposalMade { + let proposalMadeEvent = changetype(newMockEvent()) + + proposalMadeEvent.parameters = new Array() + + proposalMadeEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return proposalMadeEvent +} diff --git a/packages/subgraph/tests/simple-loan-simple-proposal.test.ts b/packages/subgraph/tests/simple-loan-simple-proposal.test.ts new file mode 100644 index 00000000..0483d561 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-simple-proposal.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/schema" +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" +import { handleProposalMade } from "../src/simple-loan-simple-proposal" +import { createProposalMadeEvent } from "./simple-loan-simple-proposal-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let proposalHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newProposalMadeEvent = createProposalMadeEvent( + proposalHash, + proposer, + proposal + ) + handleProposalMade(newProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ProposalMade created and stored", () => { + assert.entityCount("ProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposalHash", + "1234567890" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/simple-loan-utils.ts b/packages/subgraph/tests/simple-loan-utils.ts new file mode 100644 index 00000000..a2b1e216 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-utils.ts @@ -0,0 +1,267 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address, BigInt } from "@graphprotocol/graph-ts" +import { + ExtensionProposalMade, + LOANClaimed, + LOANCreated, + LOANExtended, + LOANPaidBack, + PoolSupply, + PoolWithdraw, + VaultPull, + VaultPush, + VaultPushFrom +} from "../generated/SimpleLoan/SimpleLoan" + +export function createExtensionProposalMadeEvent( + extensionHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ExtensionProposalMade { + let extensionProposalMadeEvent = + changetype(newMockEvent()) + + extensionProposalMadeEvent.parameters = new Array() + + extensionProposalMadeEvent.parameters.push( + new ethereum.EventParam( + "extensionHash", + ethereum.Value.fromFixedBytes(extensionHash) + ) + ) + extensionProposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + extensionProposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return extensionProposalMadeEvent +} + +export function createLOANClaimedEvent( + loanId: BigInt, + defaulted: boolean +): LOANClaimed { + let loanClaimedEvent = changetype(newMockEvent()) + + loanClaimedEvent.parameters = new Array() + + loanClaimedEvent.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) + ) + loanClaimedEvent.parameters.push( + new ethereum.EventParam("defaulted", ethereum.Value.fromBoolean(defaulted)) + ) + + return loanClaimedEvent +} + +export function createLOANCreatedEvent( + loanId: BigInt, + proposalHash: Bytes, + proposalContract: Address, + refinancingLoanId: BigInt, + terms: ethereum.Tuple, + lenderSpec: ethereum.Tuple, + extra: Bytes +): LOANCreated { + let loanCreatedEvent = changetype(newMockEvent()) + + loanCreatedEvent.parameters = new Array() + + loanCreatedEvent.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) + ) + loanCreatedEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + loanCreatedEvent.parameters.push( + new ethereum.EventParam( + "proposalContract", + ethereum.Value.fromAddress(proposalContract) + ) + ) + loanCreatedEvent.parameters.push( + new ethereum.EventParam( + "refinancingLoanId", + ethereum.Value.fromUnsignedBigInt(refinancingLoanId) + ) + ) + loanCreatedEvent.parameters.push( + new ethereum.EventParam("terms", ethereum.Value.fromTuple(terms)) + ) + loanCreatedEvent.parameters.push( + new ethereum.EventParam("lenderSpec", ethereum.Value.fromTuple(lenderSpec)) + ) + loanCreatedEvent.parameters.push( + new ethereum.EventParam("extra", ethereum.Value.fromBytes(extra)) + ) + + return loanCreatedEvent +} + +export function createLOANExtendedEvent( + loanId: BigInt, + originalDefaultTimestamp: BigInt, + extendedDefaultTimestamp: BigInt +): LOANExtended { + let loanExtendedEvent = changetype(newMockEvent()) + + loanExtendedEvent.parameters = new Array() + + loanExtendedEvent.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) + ) + loanExtendedEvent.parameters.push( + new ethereum.EventParam( + "originalDefaultTimestamp", + ethereum.Value.fromUnsignedBigInt(originalDefaultTimestamp) + ) + ) + loanExtendedEvent.parameters.push( + new ethereum.EventParam( + "extendedDefaultTimestamp", + ethereum.Value.fromUnsignedBigInt(extendedDefaultTimestamp) + ) + ) + + return loanExtendedEvent +} + +export function createLOANPaidBackEvent(loanId: BigInt): LOANPaidBack { + let loanPaidBackEvent = changetype(newMockEvent()) + + loanPaidBackEvent.parameters = new Array() + + loanPaidBackEvent.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) + ) + + return loanPaidBackEvent +} + +export function createPoolSupplyEvent( + asset: ethereum.Tuple, + poolAdapter: Address, + pool: Address, + owner: Address +): PoolSupply { + let poolSupplyEvent = changetype(newMockEvent()) + + poolSupplyEvent.parameters = new Array() + + poolSupplyEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) + ) + poolSupplyEvent.parameters.push( + new ethereum.EventParam( + "poolAdapter", + ethereum.Value.fromAddress(poolAdapter) + ) + ) + poolSupplyEvent.parameters.push( + new ethereum.EventParam("pool", ethereum.Value.fromAddress(pool)) + ) + poolSupplyEvent.parameters.push( + new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + ) + + return poolSupplyEvent +} + +export function createPoolWithdrawEvent( + asset: ethereum.Tuple, + poolAdapter: Address, + pool: Address, + owner: Address +): PoolWithdraw { + let poolWithdrawEvent = changetype(newMockEvent()) + + poolWithdrawEvent.parameters = new Array() + + poolWithdrawEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) + ) + poolWithdrawEvent.parameters.push( + new ethereum.EventParam( + "poolAdapter", + ethereum.Value.fromAddress(poolAdapter) + ) + ) + poolWithdrawEvent.parameters.push( + new ethereum.EventParam("pool", ethereum.Value.fromAddress(pool)) + ) + poolWithdrawEvent.parameters.push( + new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + ) + + return poolWithdrawEvent +} + +export function createVaultPullEvent( + asset: ethereum.Tuple, + origin: Address +): VaultPull { + let vaultPullEvent = changetype(newMockEvent()) + + vaultPullEvent.parameters = new Array() + + vaultPullEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) + ) + vaultPullEvent.parameters.push( + new ethereum.EventParam("origin", ethereum.Value.fromAddress(origin)) + ) + + return vaultPullEvent +} + +export function createVaultPushEvent( + asset: ethereum.Tuple, + beneficiary: Address +): VaultPush { + let vaultPushEvent = changetype(newMockEvent()) + + vaultPushEvent.parameters = new Array() + + vaultPushEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) + ) + vaultPushEvent.parameters.push( + new ethereum.EventParam( + "beneficiary", + ethereum.Value.fromAddress(beneficiary) + ) + ) + + return vaultPushEvent +} + +export function createVaultPushFromEvent( + asset: ethereum.Tuple, + origin: Address, + beneficiary: Address +): VaultPushFrom { + let vaultPushFromEvent = changetype(newMockEvent()) + + vaultPushFromEvent.parameters = new Array() + + vaultPushFromEvent.parameters.push( + new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) + ) + vaultPushFromEvent.parameters.push( + new ethereum.EventParam("origin", ethereum.Value.fromAddress(origin)) + ) + vaultPushFromEvent.parameters.push( + new ethereum.EventParam( + "beneficiary", + ethereum.Value.fromAddress(beneficiary) + ) + ) + + return vaultPushFromEvent +} diff --git a/packages/subgraph/tests/simple-loan.test.ts b/packages/subgraph/tests/simple-loan.test.ts new file mode 100644 index 00000000..b132e0be --- /dev/null +++ b/packages/subgraph/tests/simple-loan.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address, BigInt } from "@graphprotocol/graph-ts" +import { ExtensionProposalMade } from "../generated/schema" +import { ExtensionProposalMade as ExtensionProposalMadeEvent } from "../generated/SimpleLoan/SimpleLoan" +import { handleExtensionProposalMade } from "../src/simple-loan" +import { createExtensionProposalMadeEvent } from "./simple-loan-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let extensionHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newExtensionProposalMadeEvent = createExtensionProposalMadeEvent( + extensionHash, + proposer, + proposal + ) + handleExtensionProposalMade(newExtensionProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ExtensionProposalMade created and stored", () => { + assert.entityCount("ExtensionProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ExtensionProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "extensionHash", + "1234567890" + ) + assert.fieldEquals( + "ExtensionProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ExtensionProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tsconfig.json b/packages/subgraph/tsconfig.json index aecb8ec2..8aaf8a06 100644 --- a/packages/subgraph/tsconfig.json +++ b/packages/subgraph/tsconfig.json @@ -8,5 +8,9 @@ { "path": "./tsconfig.spec.json" } - ] + ], + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler" + } } diff --git a/packages/subgraph/tsconfig.lib.json b/packages/subgraph/tsconfig.lib.json index e9e008f1..cb74d040 100644 --- a/packages/subgraph/tsconfig.lib.json +++ b/packages/subgraph/tsconfig.lib.json @@ -2,14 +2,16 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "baseUrl": ".", - "rootDir": "src", "outDir": "dist", "tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo", "emitDeclarationOnly": true, "forceConsistentCasingInFileNames": true, - "types": ["node", "vite/client"] + "allowImportingTsExtensions": true, + "types": ["node", "vite/client"], + "module": "esnext", + "moduleResolution": "bundler" }, - "include": ["src/**/*.ts"], + "include": ["src/**/*.ts", "generated/**/*.ts"], "references": [], "exclude": [ "vite.config.ts", diff --git a/packages/subgraph/tsconfig.spec.json b/packages/subgraph/tsconfig.spec.json index f68d9d3b..4b76c95e 100644 --- a/packages/subgraph/tsconfig.spec.json +++ b/packages/subgraph/tsconfig.spec.json @@ -9,7 +9,9 @@ "node", "vitest" ], - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "bundler" }, "include": [ "vite.config.ts", From 5564bb9cc1a93548f6ab262248ae32cb3ad4aab2 Mon Sep 17 00:00:00 2001 From: microHoffman <61500778+microHoffman@users.noreply.github.com> Date: Tue, 10 Jun 2025 16:12:51 +0200 Subject: [PATCH 04/13] feat: multi token category entity --- packages/subgraph/schema.graphql | 23 ++++------------------- packages/subgraph/src/loan-mapping.ts | 2 ++ 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index aab3bb93..28013b3a 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -481,6 +481,7 @@ type ConfigOwnershipTransferred @entity(immutable: true) { blockTimestamp: BigInt! transactionHash: Bytes! } + type AccessControllerSet @entity(immutable: true) { id: Bytes! accessController: Bytes! # address @@ -515,30 +516,14 @@ type FeedProposed @entity(immutable: true) { transactionHash: Bytes! } -type OwnershipTransferRequested @entity(immutable: true) { - id: Bytes! - from: Bytes! # address - to: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type ChainlinkFeedRegistryOwnershipTransferred @entity(immutable: true) { - id: Bytes! - from: Bytes! # address - to: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - type Category @entity(immutable: true) { # TODO can we make this Bytes? id: Int! # category id + # TODO have here relation to Assset or AssetInCategory? + assets: [AssetInCategory!]! @derivedFrom(field: "category") } -type AssetCategory @entity(immutable: true) { +type AssetInCategory @entity(immutable: true) { id: Bytes! # asset address category: Category! } diff --git a/packages/subgraph/src/loan-mapping.ts b/packages/subgraph/src/loan-mapping.ts index 04a71040..b32fede9 100644 --- a/packages/subgraph/src/loan-mapping.ts +++ b/packages/subgraph/src/loan-mapping.ts @@ -2,6 +2,8 @@ import { Address, BigDecimal, BigInt } from "@graphprotocol/graph-ts"; import { LOANClaimed, LOANCreated, LOANPaidBack, LOANCreatedTermsCollateralStruct, LOANCreatedTermsCreditStruct, LOANExtended } from "../generated/SimpleLoan/SimpleLoan"; // Path to generated code import { Account, Asset, Loan } from "../generated/schema"; +// TODO add logs where applicable + // Helper to get or create an Account entity function getOrCreateAccount(address: Address): Account { let account = Account.load(address); From b2e0935609b84b5dd57e112395f60c1ba6ff4e20 Mon Sep 17 00:00:00 2001 From: microHoffman Date: Tue, 10 Jun 2025 19:04:15 +0200 Subject: [PATCH 05/13] feat: chainlink feeds, multitoken registry, simple loan + loan token events handlers --- packages/subgraph/schema.graphql | 545 +++++++++--------- .../subgraph/src/chainlink-feed-registry.ts | 127 ++-- packages/subgraph/src/loan-mapping.ts | 127 +--- packages/subgraph/src/loan-token.ts | 128 ++-- .../src/multi-token-category-registry.ts | 99 ++-- packages/subgraph/src/simple-loan.ts | 454 ++++++++++----- packages/subgraph/subgraph.template.yaml | 153 ++--- 7 files changed, 835 insertions(+), 798 deletions(-) diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 28013b3a..90cb3aa9 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -1,28 +1,43 @@ type Account @entity(immutable: true) { id: Bytes! # Ethereum address loansAsBorrower: [Loan!]! @derivedFrom(field: "borrower") - loansAsLender: [Loan!]! @derivedFrom(field: "lender") + loansAsLender: [Loan!]! @derivedFrom(field: "originalLender") + loansAsLoanOwner: [Loan!]! @derivedFrom(field: "loanOwner") +} + +type Category @entity(immutable: true) { + id: Bytes! # category id + assets: [AssetContract!]! @derivedFrom(field: "category") +} + +type AssetContract @entity(immutable: true) { + id: Bytes! # asset address + category: Category! + # TODO add also metadata like name / symbol / decimals? } type Asset @entity(immutable: true) { - id: String! # Combination of chainId and loanId from contract + id: Bytes! # {contract.assetAddress}{assetId} - category: Int! - assetAddress: Bytes! - assetId: BigInt! - amount: BigDecimal! + contract: AssetContract! + # TODO allow null in case of ERC20s? + tokenId: BigInt! + # TODO use BigInt? + #amount: BigDecimal! + # TODO add also metadata like name / symbol / decimals? } enum LoanStatus { Active Repaid + # TODO this state will probably never be reached right? Defaulted Claimed } type Loan @entity(immutable: false) { # Combination of chainId and loanId from contract - id: String! + id: Bytes! # {loanTokenAddress}{loanId} # Loan ID from contract event loanId: BigInt! @@ -30,35 +45,50 @@ type Loan @entity(immutable: false) { # Proposal contract address proposalContract: Bytes! + loanTokenAddress: Bytes! + + repaidAt: BigInt + claimedAt: BigInt + # Loan contract address contractAddress: Bytes! + refinancingLoanId: BigInt! + # Hash of accepted proposal proposalHash: Bytes! borrower: Account! - lender: Account! + originalLender: Account! - createdAt: BigInt! + loanOwner: Account! - # Terms + createdAt: BigInt! - # Duration duration: BigInt! - # Default deadline timestamp (createdAt + duration) - defaultDeadline: BigInt! + defaultDate: BigInt! - # Collateral collateral: Asset! + collateralAmount: BigInt! - # Credit credit: Asset! + creditAmount: BigInt! status: LoanStatus! + fixedInterestAmount: BigInt! + accruingInterestAPR: Int! + + lenderSpecHash: Bytes! + borrowerSpecHash: Bytes! + + sourceOfFunds: Bytes! + extra: Bytes! + hasDefaulted: Boolean! + # TODO also add Loan contract version? } @@ -186,21 +216,24 @@ type SimpleLoanElasticChainlinkProposalProposalMade @entity(immutable: true) { blockTimestamp: BigInt! transactionHash: Bytes! } -type ExtensionProposalMade @entity(immutable: true) { - id: Bytes! - extensionHash: Bytes! # bytes32 + +type ExtensionProposal @entity(immutable: true) { + id: Bytes! # extensionHash proposer: Bytes! # address - proposal_loanId: BigInt! # uint256 - proposal_compensationAddress: Bytes! # address - proposal_compensationAmount: BigInt! # uint256 - proposal_duration: BigInt! # uint40 - proposal_expiration: BigInt! # uint40 - proposal_proposer: Bytes! # address - proposal_nonceSpace: BigInt! # uint256 - proposal_nonce: BigInt! # uint256 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! + # TODO shall we allow null values here? + loan: Loan! + + compensationAssetAddress: Bytes! + # compensationAsset: AssetContract! + compensationAmount: BigInt + + durationToExtend: BigInt + proposalExpiration: BigInt + + nonce: BigInt! + nonceSpace: BigInt! + + createdAt: BigInt! } type LOANClaimed @entity(immutable: true) { @@ -258,109 +291,7 @@ type LOANPaidBack @entity(immutable: true) { transactionHash: Bytes! } -type PoolSupply @entity(immutable: true) { - id: Bytes! - asset_category: Int! # uint8 - asset_assetAddress: Bytes! # address - asset_id: BigInt! # uint256 - asset_amount: BigInt! # uint256 - poolAdapter: Bytes! # address - pool: Bytes! # address - owner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type PoolWithdraw @entity(immutable: true) { - id: Bytes! - asset_category: Int! # uint8 - asset_assetAddress: Bytes! # address - asset_id: BigInt! # uint256 - asset_amount: BigInt! # uint256 - poolAdapter: Bytes! # address - pool: Bytes! # address - owner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type VaultPull @entity(immutable: true) { - id: Bytes! - asset_category: Int! # uint8 - asset_assetAddress: Bytes! # address - asset_id: BigInt! # uint256 - asset_amount: BigInt! # uint256 - origin: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type VaultPush @entity(immutable: true) { - id: Bytes! - asset_category: Int! # uint8 - asset_assetAddress: Bytes! # address - asset_id: BigInt! # uint256 - asset_amount: BigInt! # uint256 - beneficiary: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type VaultPushFrom @entity(immutable: true) { - id: Bytes! - asset_category: Int! # uint8 - asset_assetAddress: Bytes! # address - asset_id: BigInt! # uint256 - asset_amount: BigInt! # uint256 - origin: Bytes! # address - beneficiary: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} -type Approval @entity(immutable: true) { - id: Bytes! - owner: Bytes! # address - approved: Bytes! # address - tokenId: BigInt! # uint256 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type ApprovalForAll @entity(immutable: true) { - id: Bytes! - owner: Bytes! # address - operator: Bytes! # address - approved: Boolean! # bool - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type LOANBurned @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type LOANMinted @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - loanContract: Bytes! # address - owner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type Transfer @entity(immutable: true) { +type LoanTokenTransfer @entity(immutable: true) { id: Bytes! from: Bytes! # address to: Bytes! # address @@ -369,47 +300,6 @@ type Transfer @entity(immutable: true) { blockTimestamp: BigInt! transactionHash: Bytes! } -type AdminChanged @entity(immutable: true) { - id: Bytes! - previousAdmin: Bytes! # address - newAdmin: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type BeaconUpgraded @entity(immutable: true) { - id: Bytes! - beacon: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type Upgraded @entity(immutable: true) { - id: Bytes! - implementation: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} -type OwnershipTransferStarted @entity(immutable: true) { - id: Bytes! - previousOwner: Bytes! # address - newOwner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type OwnershipTransferred @entity(immutable: true) { - id: Bytes! - previousOwner: Bytes! # address - newOwner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} type TagSet @entity(immutable: true) { id: Bytes! @@ -447,14 +337,6 @@ type FeeUpdated @entity(immutable: true) { transactionHash: Bytes! } -type Initialized @entity(immutable: true) { - id: Bytes! - version: Int! # uint8 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - type LOANMetadataUriUpdated @entity(immutable: true) { id: Bytes! loanContract: Bytes! # address @@ -464,83 +346,230 @@ type LOANMetadataUriUpdated @entity(immutable: true) { transactionHash: Bytes! } -type ConfigOwnershipTransferStarted @entity(immutable: true) { - id: Bytes! - previousOwner: Bytes! # address - newOwner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type ConfigOwnershipTransferred @entity(immutable: true) { - id: Bytes! - previousOwner: Bytes! # address - newOwner: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type AccessControllerSet @entity(immutable: true) { - id: Bytes! - accessController: Bytes! # address - sender: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type FeedConfirmed @entity(immutable: true) { +type ChainlinkFeed @entity(immutable: true) { id: Bytes! asset: Bytes! # address denomination: Bytes! # address - latestAggregator: Bytes! # address - previousAggregator: Bytes! # address - nextPhaseId: Int! # uint16 - sender: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type FeedProposed @entity(immutable: true) { - id: Bytes! - asset: Bytes! # address - denomination: Bytes! # address - proposedAggregator: Bytes! # address - currentAggregator: Bytes! # address - sender: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type Category @entity(immutable: true) { - # TODO can we make this Bytes? - id: Int! # category id - # TODO have here relation to Assset or AssetInCategory? - assets: [AssetInCategory!]! @derivedFrom(field: "category") -} - -type AssetInCategory @entity(immutable: true) { - id: Bytes! # asset address - category: Category! -} - -type CategoryRegistered @entity(immutable: true) { - id: Bytes! - assetAddress: Bytes! # address - category: Int! # uint8 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type CategoryUnregistered @entity(immutable: true) { - id: Bytes! - assetAddress: Bytes! # address - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} + aggregator: Bytes! # feed address +} + +# =============================== +# UNUSED ENTITIES +# =============================== + +# type LOANBurned @entity(immutable: true) { +# id: Bytes! +# loanId: BigInt! # uint256 +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type LOANMinted @entity(immutable: true) { +# id: Bytes! +# loanId: BigInt! # uint256 +# loanContract: Bytes! # address +# owner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + + +# type AdminChanged @entity(immutable: true) { +# id: Bytes! +# previousAdmin: Bytes! # address +# newAdmin: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type BeaconUpgraded @entity(immutable: true) { +# id: Bytes! +# beacon: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type Upgraded @entity(immutable: true) { +# id: Bytes! +# implementation: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type Initialized @entity(immutable: true) { +# id: Bytes! +# version: Int! # uint8 +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + + +# type Approval @entity(immutable: true) { +# id: Bytes! +# owner: Bytes! # address +# approved: Bytes! # address +# tokenId: BigInt! # uint256 +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type ApprovalForAll @entity(immutable: true) { +# id: Bytes! +# owner: Bytes! # address +# operator: Bytes! # address +# approved: Boolean! # bool +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type ConfigOwnershipTransferStarted @entity(immutable: true) { +# id: Bytes! +# previousOwner: Bytes! # address +# newOwner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type ConfigOwnershipTransferred @entity(immutable: true) { +# id: Bytes! +# previousOwner: Bytes! # address +# newOwner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type OwnershipTransferStarted @entity(immutable: true) { +# id: Bytes! +# previousOwner: Bytes! # address +# newOwner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type OwnershipTransferred @entity(immutable: true) { +# id: Bytes! +# previousOwner: Bytes! # address +# newOwner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + + +# type FeedConfirmed @entity(immutable: true) { +# id: Bytes! +# asset: Bytes! # address +# denomination: Bytes! # address +# latestAggregator: Bytes! # address +# previousAggregator: Bytes! # address +# nextPhaseId: Int! # uint16 +# sender: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type FeedProposed @entity(immutable: true) { +# id: Bytes! +# asset: Bytes! # address +# denomination: Bytes! # address +# proposedAggregator: Bytes! # address +# currentAggregator: Bytes! # address +# sender: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type CategoryRegistered @entity(immutable: true) { +# id: Bytes! +# assetAddress: Bytes! # address +# category: Int! # uint8 +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type CategoryUnregistered @entity(immutable: true) { +# id: Bytes! +# assetAddress: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type PoolSupply @entity(immutable: true) { +# id: Bytes! +# asset_category: Int! # uint8 +# asset_assetAddress: Bytes! # address +# asset_id: BigInt! # uint256 +# asset_amount: BigInt! # uint256 +# poolAdapter: Bytes! # address +# pool: Bytes! # address +# owner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type PoolWithdraw @entity(immutable: true) { +# id: Bytes! +# asset_category: Int! # uint8 +# asset_assetAddress: Bytes! # address +# asset_id: BigInt! # uint256 +# asset_amount: BigInt! # uint256 +# poolAdapter: Bytes! # address +# pool: Bytes! # address +# owner: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type VaultPull @entity(immutable: true) { +# id: Bytes! +# asset_category: Int! # uint8 +# asset_assetAddress: Bytes! # address +# asset_id: BigInt! # uint256 +# asset_amount: BigInt! # uint256 +# origin: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type VaultPush @entity(immutable: true) { +# id: Bytes! +# asset_category: Int! # uint8 +# asset_assetAddress: Bytes! # address +# asset_id: BigInt! # uint256 +# asset_amount: BigInt! # uint256 +# beneficiary: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type VaultPushFrom @entity(immutable: true) { +# id: Bytes! +# asset_category: Int! # uint8 +# asset_assetAddress: Bytes! # address +# asset_id: BigInt! # uint256 +# asset_amount: BigInt! # uint256 +# origin: Bytes! # address +# beneficiary: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } diff --git a/packages/subgraph/src/chainlink-feed-registry.ts b/packages/subgraph/src/chainlink-feed-registry.ts index 1954fa7e..f00fced2 100644 --- a/packages/subgraph/src/chainlink-feed-registry.ts +++ b/packages/subgraph/src/chainlink-feed-registry.ts @@ -1,97 +1,58 @@ import { - AccessControllerSet as AccessControllerSetEvent, FeedConfirmed as FeedConfirmedEvent, - FeedProposed as FeedProposedEvent, - OwnershipTransferRequested as OwnershipTransferRequestedEvent, - OwnershipTransferred as OwnershipTransferredEvent, } from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" import { - AccessControllerSet, - FeedConfirmed, - FeedProposed, - OwnershipTransferRequested, - OwnershipTransferred, + ChainlinkFeed, } from "../generated/schema" +import { Bytes } from "@graphprotocol/graph-ts" -export function handleAccessControllerSet( - event: AccessControllerSetEvent, -): void { - const entity = new AccessControllerSet( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.accessController = event.params.accessController - entity.sender = event.params.sender - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() +function getChainlinkFeedId(event: FeedConfirmedEvent): Bytes { + return event.params.asset.concatI32(event.params.denomination.toI32()) } export function handleFeedConfirmed(event: FeedConfirmedEvent): void { - const entity = new FeedConfirmed( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset = event.params.asset - entity.denomination = event.params.denomination - entity.latestAggregator = event.params.latestAggregator - entity.previousAggregator = event.params.previousAggregator - entity.nextPhaseId = event.params.nextPhaseId - entity.sender = event.params.sender - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleFeedProposed(event: FeedProposedEvent): void { - const entity = new FeedProposed( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset = event.params.asset - entity.denomination = event.params.denomination - entity.proposedAggregator = event.params.proposedAggregator - entity.currentAggregator = event.params.currentAggregator - entity.sender = event.params.sender - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() + const chainlinkFeedId = getChainlinkFeedId(event) + const chainlinkFeed = ChainlinkFeed.load(chainlinkFeedId) + if (chainlinkFeed == null) { + chainlinkFeed = new ChainlinkFeed(chainlinkFeedId) + } + + chainlinkFeed.asset = event.params.asset + chainlinkFeed.denomination = event.params.denomination + chainlinkFeed.aggregator = event.params.latestAggregator + chainlinkFeed.save() + + // const entity = new FeedConfirmed( + // event.transaction.hash.concatI32(event.logIndex.toI32()), + // ) + // entity.asset = event.params.asset + // entity.denomination = event.params.denomination + // entity.latestAggregator = event.params.latestAggregator + // entity.previousAggregator = event.params.previousAggregator + // entity.nextPhaseId = event.params.nextPhaseId + // entity.sender = event.params.sender + + // entity.blockNumber = event.block.number + // entity.blockTimestamp = event.block.timestamp + // entity.transactionHash = event.transaction.hash + + // entity.save() } -export function handleOwnershipTransferRequested( - event: OwnershipTransferRequestedEvent, -): void { - const entity = new OwnershipTransferRequested( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.from = event.params.from - entity.to = event.params.to - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleFeedProposed(event: FeedProposedEvent): void { +// const entity = new FeedProposed( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.asset = event.params.asset +// entity.denomination = event.params.denomination +// entity.proposedAggregator = event.params.proposedAggregator +// entity.currentAggregator = event.params.currentAggregator +// entity.sender = event.params.sender - entity.save() -} - -export function handleOwnershipTransferred( - event: OwnershipTransferredEvent, -): void { - const entity = new OwnershipTransferred( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.from = event.params.from - entity.to = event.params.to +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// entity.save() +// } - entity.save() -} diff --git a/packages/subgraph/src/loan-mapping.ts b/packages/subgraph/src/loan-mapping.ts index b32fede9..1a4a08df 100644 --- a/packages/subgraph/src/loan-mapping.ts +++ b/packages/subgraph/src/loan-mapping.ts @@ -1,11 +1,11 @@ -import { Address, BigDecimal, BigInt } from "@graphprotocol/graph-ts"; +import { Address, BigDecimal, BigInt, Bytes } from "@graphprotocol/graph-ts"; import { LOANClaimed, LOANCreated, LOANPaidBack, LOANCreatedTermsCollateralStruct, LOANCreatedTermsCreditStruct, LOANExtended } from "../generated/SimpleLoan/SimpleLoan"; // Path to generated code -import { Account, Asset, Loan } from "../generated/schema"; +import { Account, Asset, Loan, AssetContract } from "../generated/schema"; // TODO add logs where applicable // Helper to get or create an Account entity -function getOrCreateAccount(address: Address): Account { +export function getOrCreateAccount(address: Address): Account { let account = Account.load(address); if (account == null) { account = new Account(address); @@ -14,107 +14,30 @@ function getOrCreateAccount(address: Address): Account { return account; } -function getOrCreateCollateralAsset(asset: LOANCreatedTermsCollateralStruct): Asset { - const assetEntityId = `${asset.assetAddress.toHex()}-${asset.id.toString()}`; - let collateralAsset = Asset.load(assetEntityId); - if (collateralAsset == null) { - collateralAsset = new Asset(assetEntityId); - collateralAsset.category = asset.category; - collateralAsset.assetAddress = asset.assetAddress; - collateralAsset.assetId = asset.id; - collateralAsset.amount = new BigDecimal(asset.amount); - collateralAsset.save(); - } - return collateralAsset; -} - -function getOrCreateCreditAsset(asset: LOANCreatedTermsCreditStruct): Asset { - const assetEntityId = `${asset.assetAddress.toHex()}-${asset.id.toString()}`; - let creditAsset = Asset.load(assetEntityId); - if (creditAsset == null) { - creditAsset = new Asset(assetEntityId); - creditAsset.category = asset.category; - creditAsset.assetAddress = asset.assetAddress; - creditAsset.assetId = asset.id; - creditAsset.amount = new BigDecimal(asset.amount); - creditAsset.save(); - } - return creditAsset; +export function getAssetContractId(assetAddress: Address): Bytes { + return assetAddress; } -// Helper function to check if a loan should be considered defaulted based on time -function isLoanDefaulted(loan: Loan, currentTimestamp: BigInt): boolean { - // Only check for default if loan is still active - if (loan.status != "Active") { - return false; - } - - // Calculate default deadline: createdAt + duration - const defaultDeadline = loan.createdAt.plus(loan.duration); - - // Loan is defaulted if current time is past the deadline - return currentTimestamp.gt(defaultDeadline); +export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes { + return assetAddress.concat(Bytes.fromBigInt(assetId)); } -// Helper function to update loan status based on time -function updateLoanStatusIfDefaulted(loan: Loan, currentTimestamp: BigInt): void { - if (isLoanDefaulted(loan, currentTimestamp)) { - loan.status = "Defaulted"; +export function getOrCreateAsset(asset: LOANCreatedTermsCreditStruct): Asset { + let assetContract = AssetContract.load(getAssetContractId(asset.assetAddress)); + if (assetContract == null) { + assetContract = new AssetContract(getAssetContractId(asset.assetAddress)); + assetContract.category = asset.category; + assetContract.save(); } -} - -// Helper function to check and update multiple loans for defaults -// This can be called from any event handler to update loan statuses -function checkAndUpdateLoansForDefaults(currentTimestamp: BigInt, loanIds: string[]): void { - for (let i = 0; i < loanIds.length; i++) { - const loan = Loan.load(loanIds[i]); - if (loan && loan.status == "Active") { - updateLoanStatusIfDefaulted(loan, currentTimestamp); - loan.save(); - } + let assetResult = Asset.load(getAssetId(asset.assetAddress, asset.id)); + if (assetResult == null) { + assetResult = new Asset(getAssetId(asset.assetAddress, asset.id)); + assetResult.contract = assetContract.id; + assetResult.tokenId = asset.id; + // assetResult.amount = new BigDecimal(asset.amount); + assetResult.save(); } -} - -export function handleLOANCreated(event: LOANCreated): void { - const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; - const loan = new Loan(loanEntityId); - - loan.loanId = event.params.loanId; - loan.proposalHash = event.params.proposalHash; - loan.contractAddress = event.address; - loan.proposalContract = event.params.proposalContract; - - const terms = event.params.terms; - - loan.borrower = getOrCreateAccount(terms.borrower).id; - loan.lender = getOrCreateAccount(terms.lender).id; - - loan.createdAt = event.block.timestamp; - - // terms setting - loan.duration = terms.duration; - // Calculate and store the default deadline for easier querying - // loan.defaultDeadline = event.block.timestamp.plus(terms.duration); // Uncomment after codegen - loan.collateral = getOrCreateCollateralAsset(terms.collateral).id; - loan.credit = getOrCreateCreditAsset(terms.credit).id; - - loan.status = "Active"; - - loan.extra = event.params.extra; - - loan.save(); - -} - -export function handleLOANPaidBack(event: LOANPaidBack): void { - const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; - const loan = Loan.load(loanEntityId); - if (!loan) return; - - loan.status = "Repaid"; - loan.save(); - - // TODO: Update the linked Proposal entity status + return assetResult } // Updated function to handle both explicit defaults and time-based defaults @@ -123,13 +46,7 @@ export function handleLOANClaimed(event: LOANClaimed): void { const loan = Loan.load(loanEntityId); if (!loan) return; - if (event.params.defaulted) { - loan.status = "Defaulted"; - } else { - // Even if not explicitly defaulted, check if it should be considered defaulted based on time - updateLoanStatusIfDefaulted(loan, event.block.timestamp); - } - + loan.status = "Claimed"; loan.save(); } diff --git a/packages/subgraph/src/loan-token.ts b/packages/subgraph/src/loan-token.ts index f8758a19..5159916a 100644 --- a/packages/subgraph/src/loan-token.ts +++ b/packages/subgraph/src/loan-token.ts @@ -1,24 +1,33 @@ import { - Approval as ApprovalEvent, - ApprovalForAll as ApprovalForAllEvent, - LOANBurned as LOANBurnedEvent, - LOANMinted as LOANMintedEvent, + LoanToken, Transfer as TransferEvent, } from "../generated/LoanToken/LoanToken" import { - Approval, - ApprovalForAll, - LOANBurned, - LOANMinted, - Transfer, + Loan, + LoanTokenTransfer, } from "../generated/schema" +import { getOrCreateAccount } from "./loan-mapping" +import { getLoanId } from "./simple-loan" -export function handleApproval(event: ApprovalEvent): void { - const entity = new Approval( +export function handleTransfer(event: TransferEvent): void { + const loanTokenContract = LoanToken.bind(event.address) + const loanContractAddress = loanTokenContract.loanContract(event.params.tokenId) + + const loan = Loan.load(getLoanId(loanContractAddress, event.params.tokenId)) + + if (!loan) { + return + } + + loan.loanOwner = getOrCreateAccount(event.params.to).id + loan.save() + + + const entity = new LoanTokenTransfer( event.transaction.hash.concatI32(event.logIndex.toI32()), ) - entity.owner = event.params.owner - entity.approved = event.params.approved + entity.from = event.params.from + entity.to = event.params.to entity.tokenId = event.params.tokenId entity.blockNumber = event.block.number @@ -28,60 +37,61 @@ export function handleApproval(event: ApprovalEvent): void { entity.save() } -export function handleApprovalForAll(event: ApprovalForAllEvent): void { - const entity = new ApprovalForAll( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.owner = event.params.owner - entity.operator = event.params.operator - entity.approved = event.params.approved - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleLOANBurned(event: LOANBurnedEvent): void { +// const entity = new LOANBurned( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanId = event.params.loanId - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handleLOANBurned(event: LOANBurnedEvent): void { - const entity = new LOANBurned( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.loanId = event.params.loanId +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleLOANMinted(event: LOANMintedEvent): void { +// const entity = new LOANMinted( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanId = event.params.loanId +// entity.loanContract = event.params.loanContract +// entity.owner = event.params.owner - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handleLOANMinted(event: LOANMintedEvent): void { - const entity = new LOANMinted( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.loanId = event.params.loanId - entity.loanContract = event.params.loanContract - entity.owner = event.params.owner +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleApproval(event: ApprovalEvent): void { +// const entity = new Approval( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.owner = event.params.owner +// entity.approved = event.params.approved +// entity.tokenId = event.params.tokenId - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handleTransfer(event: TransferEvent): void { - const entity = new Transfer( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.from = event.params.from - entity.to = event.params.to - entity.tokenId = event.params.tokenId +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleApprovalForAll(event: ApprovalForAllEvent): void { +// const entity = new ApprovalForAll( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.owner = event.params.owner +// entity.operator = event.params.operator +// entity.approved = event.params.approved - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } diff --git a/packages/subgraph/src/multi-token-category-registry.ts b/packages/subgraph/src/multi-token-category-registry.ts index d39bbe47..c28fbb65 100644 --- a/packages/subgraph/src/multi-token-category-registry.ts +++ b/packages/subgraph/src/multi-token-category-registry.ts @@ -1,83 +1,62 @@ import { CategoryRegistered as CategoryRegisteredEvent, CategoryUnregistered as CategoryUnregisteredEvent, - OwnershipTransferStarted as OwnershipTransferStartedEvent, - OwnershipTransferred as OwnershipTransferredEvent, } from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" import { - CategoryRegistered, - CategoryUnregistered, - OwnershipTransferStarted, - OwnershipTransferred, + AssetInCategory, Category, - AssetCategory, } from "../generated/schema" import { store } from '@graphprotocol/graph-ts' +import { Bytes } from "@graphprotocol/graph-ts" export function handleCategoryRegistered(event: CategoryRegisteredEvent): void { - let category = Category.load(event.params.category) + const categoryId = Bytes.fromI32(event.params.category) + let category = Category.load(categoryId) if (category == null) { - category = new Category(event.params.category) + category = new Category(categoryId) category.save() } - let assetCategory = Category.load() - - const entity = new CategoryRegistered( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.assetAddress = event.params.assetAddress - entity.category = event.params.category - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + let assetCategory = AssetInCategory.load(event.params.assetAddress) + if (assetCategory == null) { + assetCategory = new AssetInCategory(event.params.assetAddress) + } - entity.save() + assetCategory.category = event.params.category + assetCategory.save() + + // TODO shall we save also the raw event? + // const entity = new CategoryRegistered( + // event.transaction.hash.concatI32(event.logIndex.toI32()), + // ) + // entity.assetAddress = event.params.assetAddress + // entity.category = event.params.category + + // entity.blockNumber = event.block.number + // entity.blockTimestamp = event.block.timestamp + // entity.transactionHash = event.transaction.hash + + // entity.save() } export function handleCategoryUnregistered( event: CategoryUnregisteredEvent, ): void { - const entity = new CategoryUnregistered( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.assetAddress = event.params.assetAddress - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleOwnershipTransferStarted( - event: OwnershipTransferStartedEvent, -): void { - const entity = new OwnershipTransferStarted( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousOwner = event.params.previousOwner - entity.newOwner = event.params.newOwner - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} + const assetInCategory = AssetInCategory.load(event.params.assetAddress) + if (assetInCategory == null) { + // no need to do anything here + return + } + store.remove("AssetInCategory", event.params.assetAddress) -export function handleOwnershipTransferred( - event: OwnershipTransferredEvent, -): void { - const entity = new OwnershipTransferred( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousOwner = event.params.previousOwner - entity.newOwner = event.params.newOwner + // TODO shall we save also the raw event? + // const entity = new CategoryUnregistered( + // event.transaction.hash.concatI32(event.logIndex.toI32()), + // ) + // entity.assetAddress = event.params.assetAddress - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + // entity.blockNumber = event.block.number + // entity.blockTimestamp = event.block.timestamp + // entity.transactionHash = event.transaction.hash - entity.save() + // entity.save() } diff --git a/packages/subgraph/src/simple-loan.ts b/packages/subgraph/src/simple-loan.ts index cfc8989a..1f0930ce 100644 --- a/packages/subgraph/src/simple-loan.ts +++ b/packages/subgraph/src/simple-loan.ts @@ -1,102 +1,106 @@ +import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts" import { ExtensionProposalMade as ExtensionProposalMadeEvent, LOANClaimed as LOANClaimedEvent, LOANCreated as LOANCreatedEvent, LOANExtended as LOANExtendedEvent, LOANPaidBack as LOANPaidBackEvent, - PoolSupply as PoolSupplyEvent, - PoolWithdraw as PoolWithdrawEvent, - VaultPull as VaultPullEvent, - VaultPush as VaultPushEvent, - VaultPushFrom as VaultPushFromEvent, + SimpleLoan, } from "../generated/SimpleLoan/SimpleLoan" import { - ExtensionProposalMade, - LOANClaimed, - LOANCreated, + ExtensionProposal, LOANExtended, - LOANPaidBack, - PoolSupply, - PoolWithdraw, - VaultPull, - VaultPush, - VaultPushFrom, + Loan, } from "../generated/schema" +import { getOrCreateAccount, getOrCreateAsset } from "./loan-mapping" -export function handleExtensionProposalMade( - event: ExtensionProposalMadeEvent, -): void { - const entity = new ExtensionProposalMade( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.extensionHash = event.params.extensionHash - entity.proposer = event.params.proposer - entity.proposal_loanId = event.params.proposal.loanId - entity.proposal_compensationAddress = - event.params.proposal.compensationAddress - entity.proposal_compensationAmount = event.params.proposal.compensationAmount - entity.proposal_duration = event.params.proposal.duration - entity.proposal_expiration = event.params.proposal.expiration - entity.proposal_proposer = event.params.proposal.proposer - entity.proposal_nonceSpace = event.params.proposal.nonceSpace - entity.proposal_nonce = event.params.proposal.nonce +export function getLoanId(loanContractAddress: Address, loanId: BigInt): Bytes { + return loanContractAddress.concat(Bytes.fromBigInt(loanId)) +} - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +export function handleLOANCreated(event: LOANCreatedEvent): void { + const loanId = getLoanId(event.address, event.params.loanId) + const loan = new Loan(loanId) + loan.loanId = event.params.loanId + loan.contractAddress = event.address + loan.proposalHash = event.params.proposalHash + loan.proposalContract = event.params.proposalContract + loan.refinancingLoanId = event.params.refinancingLoanId + loan.originalLender = getOrCreateAccount(event.params.terms.lender).id + loan.loanOwner = getOrCreateAccount(event.params.terms.lender).id + loan.borrower = getOrCreateAccount(event.params.terms.borrower).id + loan.duration = event.params.terms.duration - entity.save() + loan.createdAt = event.block.timestamp + + loan.collateral = getOrCreateAsset(event.params.terms.collateral).id + loan.collateralAmount = event.params.terms.collateral.amount + loan.credit = getOrCreateAsset(event.params.terms.credit).id + loan.creditAmount = event.params.terms.credit.amount + + loan.status = "Active" + + loan.fixedInterestAmount = event.params.terms.fixedInterestAmount + loan.accruingInterestAPR = event.params.terms.accruingInterestAPR + + loan.lenderSpecHash = event.params.terms.lenderSpecHash + loan.borrowerSpecHash = event.params.terms.borrowerSpecHash + + loan.sourceOfFunds = event.params.lenderSpec.sourceOfFunds + + loan.defaultDate = event.params.terms.duration.plus(loan.createdAt) + + loan.extra = event.params.extra + + const simpleLoanContract = SimpleLoan.bind(loan.contractAddress) + loan.loanTokenAddress = simpleLoanContract.loanToken() + + loan.save() } -export function handleLOANClaimed(event: LOANClaimedEvent): void { - const entity = new LOANClaimed( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.loanId = event.params.loanId - entity.defaulted = event.params.defaulted +export function handleLOANPaidBack(event: LOANPaidBackEvent): void { + const loanId = getLoanId(event.address, event.params.loanId) + const loan = Loan.load(loanId) + if (!loan) { + // TODO what to do in this case? + return + } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + loan.status = "Repaid" + loan.repaidAt = event.block.timestamp + loan.save() - entity.save() + // TODO: Update the linked Proposal entity status } -export function handleLOANCreated(event: LOANCreatedEvent): void { - const entity = new LOANCreated( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.loanId = event.params.loanId - entity.proposalHash = event.params.proposalHash - entity.proposalContract = event.params.proposalContract - entity.refinancingLoanId = event.params.refinancingLoanId - entity.terms_lender = event.params.terms.lender - entity.terms_borrower = event.params.terms.borrower - entity.terms_duration = event.params.terms.duration - entity.terms_collateral_category = event.params.terms.collateral.category - entity.terms_collateral_assetAddress = - event.params.terms.collateral.assetAddress - entity.terms_collateral_id = event.params.terms.collateral.id - entity.terms_collateral_amount = event.params.terms.collateral.amount - entity.terms_credit_category = event.params.terms.credit.category - entity.terms_credit_assetAddress = event.params.terms.credit.assetAddress - entity.terms_credit_id = event.params.terms.credit.id - entity.terms_credit_amount = event.params.terms.credit.amount - entity.terms_fixedInterestAmount = event.params.terms.fixedInterestAmount - entity.terms_accruingInterestAPR = event.params.terms.accruingInterestAPR - entity.terms_lenderSpecHash = event.params.terms.lenderSpecHash - entity.terms_borrowerSpecHash = event.params.terms.borrowerSpecHash - entity.lenderSpec_sourceOfFunds = event.params.lenderSpec.sourceOfFunds - entity.extra = event.params.extra +export function handleLOANClaimed(event: LOANClaimedEvent): void { + const loanId = getLoanId(event.address, event.params.loanId) + const loan = Loan.load(loanId) + if (!loan) { + // TODO what to do in this case? + return + } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + loan.status = "Claimed" + loan.claimedAt = event.block.timestamp + loan.hasDefaulted = event.params.defaulted + loan.save() - entity.save() + // TODO: Update the linked Proposal entity status } export function handleLOANExtended(event: LOANExtendedEvent): void { + const loanId = getLoanId(event.address, event.params.loanId) + const loan = Loan.load(loanId) + if (!loan) { + // TODO what to do in this case? + return + } + + loan.defaultDate = event.params.extendedDefaultTimestamp + loan.save() + + // save the event as well const entity = new LOANExtended( event.transaction.hash.concatI32(event.logIndex.toI32()), ) @@ -111,105 +115,237 @@ export function handleLOANExtended(event: LOANExtendedEvent): void { entity.save() } -export function handleLOANPaidBack(event: LOANPaidBackEvent): void { - const entity = new LOANPaidBack( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.loanId = event.params.loanId +export function handleExtensionProposalMade( + event: ExtensionProposalMadeEvent, +): void { + const extensionProposal = new ExtensionProposal(event.params.extensionHash) + extensionProposal.proposer = event.params.proposer + const loanId = getLoanId(event.address, event.params.proposal.loanId) + const loan = Loan.load(loanId) + if (!loan) { + // TODO what to do in this case? + return + } + extensionProposal.loan = loan.id + extensionProposal.compensationAssetAddress = event.params.proposal.compensationAddress + extensionProposal.compensationAmount = event.params.proposal.compensationAmount + extensionProposal.durationToExtend = event.params.proposal.duration + extensionProposal.proposalExpiration = event.params.proposal.expiration + extensionProposal.nonceSpace = event.params.proposal.nonceSpace + extensionProposal.nonce = event.params.proposal.nonce + extensionProposal.createdAt = event.block.timestamp + extensionProposal.save() - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + // const entity = new ExtensionProposalMade( + // event.transaction.hash.concatI32(event.logIndex.toI32()), + // ) + // entity.extensionHash = event.params.extensionHash + // entity.proposer = event.params.proposer + // entity.proposal_loanId = event.params.proposal.loanId + // entity.proposal_compensationAddress = + // event.params.proposal.compensationAddress + // entity.proposal_compensationAmount = event.params.proposal.compensationAmount + // entity.proposal_duration = event.params.proposal.duration + // entity.proposal_expiration = event.params.proposal.expiration + // entity.proposal_proposer = event.params.proposal.proposer + // entity.proposal_nonceSpace = event.params.proposal.nonceSpace + // entity.proposal_nonce = event.params.proposal.nonce - entity.save() + // entity.blockNumber = event.block.number + // entity.blockTimestamp = event.block.timestamp + // entity.transactionHash = event.transaction.hash + + // entity.save() } -export function handlePoolSupply(event: PoolSupplyEvent): void { - const entity = new PoolSupply( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset_category = event.params.asset.category - entity.asset_assetAddress = event.params.asset.assetAddress - entity.asset_id = event.params.asset.id - entity.asset_amount = event.params.asset.amount - entity.poolAdapter = event.params.poolAdapter - entity.pool = event.params.pool - entity.owner = event.params.owner +// ====== UNUSED CODE - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleLOANClaimed(event: LOANClaimedEvent): void { +// const entity = new LOANClaimed( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanId = event.params.loanId +// entity.defaulted = event.params.defaulted - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handlePoolWithdraw(event: PoolWithdrawEvent): void { - const entity = new PoolWithdraw( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset_category = event.params.asset.category - entity.asset_assetAddress = event.params.asset.assetAddress - entity.asset_id = event.params.asset.id - entity.asset_amount = event.params.asset.amount - entity.poolAdapter = event.params.poolAdapter - entity.pool = event.params.pool - entity.owner = event.params.owner +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleLOANExtended(event: LOANExtendedEvent): void { +// const entity = new LOANExtended( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanId = event.params.loanId +// entity.originalDefaultTimestamp = event.params.originalDefaultTimestamp +// entity.extendedDefaultTimestamp = event.params.extendedDefaultTimestamp - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handleVaultPull(event: VaultPullEvent): void { - const entity = new VaultPull( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset_category = event.params.asset.category - entity.asset_assetAddress = event.params.asset.assetAddress - entity.asset_id = event.params.asset.id - entity.asset_amount = event.params.asset.amount - entity.origin = event.params.origin +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handleExtensionProposalMade( +// event: ExtensionProposalMadeEvent, +// ): void { +// const entity = new ExtensionProposalMade( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.extensionHash = event.params.extensionHash +// entity.proposer = event.params.proposer +// entity.proposal_loanId = event.params.proposal.loanId +// entity.proposal_compensationAddress = +// event.params.proposal.compensationAddress +// entity.proposal_compensationAmount = event.params.proposal.compensationAmount +// entity.proposal_duration = event.params.proposal.duration +// entity.proposal_expiration = event.params.proposal.expiration +// entity.proposal_proposer = event.params.proposal.proposer +// entity.proposal_nonceSpace = event.params.proposal.nonceSpace +// entity.proposal_nonce = event.params.proposal.nonce - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handleVaultPush(event: VaultPushEvent): void { - const entity = new VaultPush( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset_category = event.params.asset.category - entity.asset_assetAddress = event.params.asset.assetAddress - entity.asset_id = event.params.asset.id - entity.asset_amount = event.params.asset.amount - entity.beneficiary = event.params.beneficiary +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handlePoolSupply(event: PoolSupplyEvent): void { +// const entity = new PoolSupply( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.asset_category = event.params.asset.category +// entity.asset_assetAddress = event.params.asset.assetAddress +// entity.asset_id = event.params.asset.id +// entity.asset_amount = event.params.asset.amount +// entity.poolAdapter = event.params.poolAdapter +// entity.pool = event.params.pool +// entity.owner = event.params.owner - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash -export function handleVaultPushFrom(event: VaultPushFromEvent): void { - const entity = new VaultPushFrom( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.asset_category = event.params.asset.category - entity.asset_assetAddress = event.params.asset.assetAddress - entity.asset_id = event.params.asset.id - entity.asset_amount = event.params.asset.amount - entity.origin = event.params.origin - entity.beneficiary = event.params.beneficiary +// entity.save() +// } - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash +// export function handlePoolWithdraw(event: PoolWithdrawEvent): void { +// const entity = new PoolWithdraw( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.asset_category = event.params.asset.category +// entity.asset_assetAddress = event.params.asset.assetAddress +// entity.asset_id = event.params.asset.id +// entity.asset_amount = event.params.asset.amount +// entity.poolAdapter = event.params.poolAdapter +// entity.pool = event.params.pool +// entity.owner = event.params.owner - entity.save() -} +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleVaultPull(event: VaultPullEvent): void { +// const entity = new VaultPull( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.asset_category = event.params.asset.category +// entity.asset_assetAddress = event.params.asset.assetAddress +// entity.asset_id = event.params.asset.id +// entity.asset_amount = event.params.asset.amount +// entity.origin = event.params.origin + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleVaultPush(event: VaultPushEvent): void { +// const entity = new VaultPush( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.asset_category = event.params.asset.category +// entity.asset_assetAddress = event.params.asset.assetAddress +// entity.asset_id = event.params.asset.id +// entity.asset_amount = event.params.asset.amount +// entity.beneficiary = event.params.beneficiary + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleVaultPushFrom(event: VaultPushFromEvent): void { +// const entity = new VaultPushFrom( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.asset_category = event.params.asset.category +// entity.asset_assetAddress = event.params.asset.assetAddress +// entity.asset_id = event.params.asset.id +// entity.asset_amount = event.params.asset.amount +// entity.origin = event.params.origin +// entity.beneficiary = event.params.beneficiary + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// handleLoanClaimed: +// const entity = new LOANCreated( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanId = event.params.loanId +// entity.proposalHash = event.params.proposalHash +// entity.proposalContract = event.params.proposalContract +// entity.refinancingLoanId = event.params.refinancingLoanId +// entity.terms_lender = event.params.terms.lender +// entity.terms_borrower = event.params.terms.borrower +// entity.terms_duration = event.params.terms.duration +// entity.terms_collateral_category = event.params.terms.collateral.category +// entity.terms_collateral_assetAddress = +// event.params.terms.collateral.assetAddress +// entity.terms_collateral_id = event.params.terms.collateral.id +// entity.terms_collateral_amount = event.params.terms.collateral.amount +// entity.terms_credit_category = event.params.terms.credit.category +// entity.terms_credit_assetAddress = event.params.terms.credit.assetAddress +// entity.terms_credit_id = event.params.terms.credit.id +// entity.terms_credit_amount = event.params.terms.credit.amount +// entity.terms_fixedInterestAmount = event.params.terms.fixedInterestAmount +// entity.terms_accruingInterestAPR = event.params.terms.accruingInterestAPR +// entity.terms_lenderSpecHash = event.params.terms.lenderSpecHash +// entity.terms_borrowerSpecHash = event.params.terms.borrowerSpecHash +// entity.lenderSpec_sourceOfFunds = event.params.lenderSpec.sourceOfFunds +// entity.extra = event.params.extra + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() + +// export function handleLOANPaidBack(event: LOANPaidBackEvent): void { +// const entity = new LOANPaidBack( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanId = event.params.loanId + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } \ No newline at end of file diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index a05644b8..7dc95b21 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -110,11 +110,11 @@ dataSources: - LOANCreated - LOANExtended - LOANPaidBack - - PoolSupply - - PoolWithdraw - - VaultPull - - VaultPush - - VaultPushFrom + #- PoolSupply + #- PoolWithdraw + #- VaultPull + #- VaultPush + #- VaultPushFrom abis: - name: SimpleLoan file: ./abis/SimpleLoan.json @@ -131,18 +131,18 @@ dataSources: handler: handleLOANExtended - event: LOANPaidBack(indexed uint256) handler: handleLOANPaidBack - - event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed - address) - handler: handlePoolSupply - - event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed - address,indexed address) - handler: handlePoolWithdraw - - event: VaultPull((uint8,address,uint256,uint256),indexed address) - handler: handleVaultPull - - event: VaultPush((uint8,address,uint256,uint256),indexed address) - handler: handleVaultPush - - event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) - handler: handleVaultPushFrom + #- event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed + # address) + # handler: handlePoolSupply + #- event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed + # address,indexed address) + # handler: handlePoolWithdraw + #- event: VaultPull((uint8,address,uint256,uint256),indexed address) + # handler: handleVaultPull + #- event: VaultPush((uint8,address,uint256,uint256),indexed address) + # handler: handleVaultPush + #- event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) + # handler: handleVaultPushFrom file: ./src/simple-loan.ts - kind: ethereum name: LoanToken @@ -156,23 +156,25 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - Approval - - ApprovalForAll - - LOANBurned - - LOANMinted + # - Approval + # - ApprovalForAll + #- LOANBurned + #- LOANMinted - Transfer abis: - name: LoanToken file: ./abis/LoanToken.json eventHandlers: - - event: Approval(indexed address,indexed address,indexed uint256) - handler: handleApproval - - event: ApprovalForAll(indexed address,indexed address,bool) - handler: handleApprovalForAll - - event: LOANBurned(indexed uint256) - handler: handleLOANBurned - - event: LOANMinted(indexed uint256,indexed address,indexed address) - handler: handleLOANMinted + # - event: Approval(indexed address,indexed address,indexed uint256) + # handler: handleApproval + # - event: ApprovalForAll(indexed address,indexed address,bool) + # handler: handleApprovalForAll + # note: no need to track LOANBurned and LOANMinted as they happen always + # together with LOANCreated and LOANClaimed + #- event: LOANBurned(indexed uint256) + # handler: handleLOANBurned + #- event: LOANMinted(indexed uint256,indexed address,indexed address) + # handler: handleLOANMinted - event: Transfer(indexed address,indexed address,indexed uint256) handler: handleTransfer file: ./src/loan-token.ts @@ -190,40 +192,40 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - AdminChanged - - BeaconUpgraded - - Upgraded + #- AdminChanged + #- BeaconUpgraded + #- Upgraded - DefaultLOANMetadataUriUpdated - FeeCollectorUpdated - FeeUpdated - - Initialized + #- Initialized - LOANMetadataUriUpdated - - ConfigOwnershipTransferStarted - - ConfigOwnershipTransferred + #- ConfigOwnershipTransferStarted + #- ConfigOwnershipTransferred abis: - name: Config file: ./abis/Config.json eventHandlers: - - event: AdminChanged(address,address) - handler: handleAdminChanged - - event: BeaconUpgraded(indexed address) - handler: handleBeaconUpgraded - - event: Upgraded(indexed address) - handler: handleUpgraded + #- event: AdminChanged(address,address) + # handler: handleAdminChanged + #- event: BeaconUpgraded(indexed address) + # handler: handleBeaconUpgraded + #- event: Upgraded(indexed address) + # handler: handleUpgraded - event: DefaultLOANMetadataUriUpdated(string) handler: handleDefaultLOANMetadataUriUpdated - event: FeeCollectorUpdated(address,address) handler: handleFeeCollectorUpdated - event: FeeUpdated(uint16,uint16) handler: handleFeeUpdated - - event: Initialized(uint8) - handler: handleInitialized + #- event: Initialized(uint8) + # handler: handleInitialized - event: LOANMetadataUriUpdated(indexed address,string) handler: handleLOANMetadataUriUpdated - - event: OwnershipTransferStarted(indexed address,indexed address) - handler: handleOwnershipTransferStarted - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: OwnershipTransferStarted(indexed address,indexed address) + # handler: handleOwnershipTransferStarted + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred file: ./src/config.ts - kind: ethereum name: Hub @@ -237,17 +239,17 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - OwnershipTransferStarted - - OwnershipTransferred + #- OwnershipTransferStarted + #- OwnershipTransferred - TagSet abis: - name: Hub file: ./abis/Hub.json eventHandlers: - - event: OwnershipTransferStarted(indexed address,indexed address) - handler: handleOwnershipTransferStarted - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: OwnershipTransferStarted(indexed address,indexed address) + # handler: handleOwnershipTransferStarted + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred - event: TagSet(indexed address,indexed bytes32,bool) handler: handleTagSet file: ./src/hub.ts @@ -263,26 +265,27 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - AccessControllerSet - - FeedConfirmed - - FeedProposed - - OwnershipTransferRequested - - ChainlinkFeedRegistryOwnershipTransferred + #- AccessControllerSet + - ChainlinkFeed + #- FeedConfirmed + #- FeedProposed + #- OwnershipTransferRequested + #- ChainlinkFeedRegistryOwnershipTransferred abis: - name: ChainlinkFeedRegistry file: ./abis/ChainlinkFeedRegistry.json eventHandlers: - - event: AccessControllerSet(indexed address,indexed address) - handler: handleAccessControllerSet + #- event: AccessControllerSet(indexed address,indexed address) + # handler: handleAccessControllerSet - event: FeedConfirmed(indexed address,indexed address,indexed address,address,uint16,address) handler: handleFeedConfirmed - - event: FeedProposed(indexed address,indexed address,indexed address,address,address) - handler: handleFeedProposed - - event: OwnershipTransferRequested(indexed address,indexed address) - handler: handleOwnershipTransferRequested - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: FeedProposed(indexed address,indexed address,indexed address,address,address) + # handler: handleFeedProposed + #- event: OwnershipTransferRequested(indexed address,indexed address) + # handler: handleOwnershipTransferRequested + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred file: ./src/chainlink-feed-registry.ts - kind: ethereum name: MultiTokenCategoryRegistry @@ -296,10 +299,12 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - CategoryRegistered - - CategoryUnregistered - - MultiTokenCategoryRegistryOwnershipTransferStarted - - MultiTokenCategoryRegistryOwnershipTransferred + - AssetInCategory + - Category + #- CategoryRegistered + #- CategoryUnregistered + #- MultiTokenCategoryRegistryOwnershipTransferStarted + #- MultiTokenCategoryRegistryOwnershipTransferred abis: - name: MultiTokenCategoryRegistry file: ./abis/MultiTokenCategoryRegistry.json @@ -308,9 +313,9 @@ dataSources: handler: handleCategoryRegistered - event: CategoryUnregistered(indexed address) handler: handleCategoryUnregistered - - event: OwnershipTransferStarted(indexed address,indexed address) - handler: handleOwnershipTransferStarted - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: OwnershipTransferStarted(indexed address,indexed address) + # handler: handleOwnershipTransferStarted + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred file: ./src/multi-token-category-registry.ts From 7dd364409efa89f20b537159faa1940c08c06b8e Mon Sep 17 00:00:00 2001 From: microHoffman Date: Tue, 10 Jun 2025 23:33:40 +0200 Subject: [PATCH 06/13] feat: subgraph --- ...mpleLoanUniswapV3LPIndividualProposal.json | 1060 ++++++++++++++++ .../SimpleLoanUniswapV3LPSetProposal.json | 1101 +++++++++++++++++ packages/subgraph/config/mainnet.json | 5 + packages/subgraph/config/sepolia.json | 8 + packages/subgraph/schema.graphql | 540 +++++--- .../subgraph/src/chainlink-feed-registry.ts | 2 +- packages/subgraph/src/config.ts | 334 +++-- .../src/entity-helpers/get-or-create.ts | 0 packages/subgraph/src/entity-helpers/ids.ts | 0 packages/subgraph/src/helpers.ts | 20 + packages/subgraph/src/hub.ts | 36 - packages/subgraph/src/loan-mapping.ts | 69 -- packages/subgraph/src/loan-token.ts | 2 +- .../src/multi-token-category-registry.ts | 19 +- .../simple-loan-elastic-chainlink-proposal.ts | 127 +- .../src/simple-loan-elastic-proposal.ts | 120 +- .../subgraph/src/simple-loan-list-proposal.ts | 121 +- .../src/simple-loan-simple-proposal.ts | 120 +- ...loan-uniswap-v-3-lp-individual-proposal.ts | 108 ++ ...simple-loan-uniswap-v-3-lp-set-proposal.ts | 112 ++ packages/subgraph/src/simple-loan.ts | 14 +- packages/subgraph/src/utils.ts | 86 ++ packages/subgraph/subgraph.template.yaml | 43 +- packages/subgraph/subgraph.yaml | 258 ++-- ...niswap-v-3-lp-individual-proposal-utils.ts | 28 + ...uniswap-v-3-lp-individual-proposal.test.ts | 66 + ...-loan-uniswap-v-3-lp-set-proposal-utils.ts | 28 + ...e-loan-uniswap-v-3-lp-set-proposal.test.ts | 66 + 28 files changed, 3817 insertions(+), 676 deletions(-) create mode 100644 packages/subgraph/abis/SimpleLoanUniswapV3LPIndividualProposal.json create mode 100644 packages/subgraph/abis/SimpleLoanUniswapV3LPSetProposal.json create mode 100644 packages/subgraph/src/entity-helpers/get-or-create.ts create mode 100644 packages/subgraph/src/entity-helpers/ids.ts create mode 100644 packages/subgraph/src/helpers.ts delete mode 100644 packages/subgraph/src/loan-mapping.ts create mode 100644 packages/subgraph/src/simple-loan-uniswap-v-3-lp-individual-proposal.ts create mode 100644 packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts create mode 100644 packages/subgraph/src/utils.ts create mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts create mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts create mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts create mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts diff --git a/packages/subgraph/abis/SimpleLoanUniswapV3LPIndividualProposal.json b/packages/subgraph/abis/SimpleLoanUniswapV3LPIndividualProposal.json new file mode 100644 index 00000000..c17a665d --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanUniswapV3LPIndividualProposal.json @@ -0,0 +1,1060 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { + "internalType": "address", + "name": "_utilizedCredit", + "type": "address" + }, + { + "internalType": "address", + "name": "_uniswapV3Factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_uniswapNFTPositionManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkFeedRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkL2SequencerUptimeFeed", + "type": "address" + }, + { "internalType": "address", "name": "_weth", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "AcceptorIsProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "CallerIsNotStatedProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "address", "name": "loanContract", "type": "address" } + ], + "name": "CallerNotLoanContract", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" } + ], + "name": "ChainlinkFeedPriceTooOld", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "int256", "name": "price", "type": "int256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" } + ], + "name": "ChainlinkFeedReturnedNegativePrice", + "type": "error" + }, + { "inputs": [], "name": "ChainlinkInvalidInputLenghts", "type": "error" }, + { + "inputs": [ + { "internalType": "uint32", "name": "defaultDate", "type": "uint32" }, + { "internalType": "uint32", "name": "current", "type": "uint32" } + ], + "name": "DefaultDateInPast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "timeSinceUp", "type": "uint256" }, + { "internalType": "uint256", "name": "gracePeriod", "type": "uint256" } + ], + "name": "GracePeriodNotOver", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "InsufficientCreditAmount", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "IntermediaryDenominationsOutOfBounds", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + } + ], + "name": "InvalidAcceptorController", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "proposed", "type": "bytes32" } + ], + "name": "InvalidCollateralStateFingerprint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + } + ], + "name": "InvalidRefinancingLoanId", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { "inputs": [], "name": "L2SequencerDown", "type": "error" }, + { "inputs": [], "name": "MinCreditAmountNotSet", "type": "error" }, + { "inputs": [], "name": "MissingStateFingerprintComputer", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { "inputs": [], "name": "T", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "token0Denominator", + "type": "bool" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ProposalMade", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOAN_TO_VALUE_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_INTERMEDIARY_DENOMINATIONS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "acceptor", "type": "address" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "acceptProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoan.Terms", + "name": "loanTerms", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkFeedRegistry", + "outputs": [ + { + "internalType": "contract IChainlinkFeedRegistryLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkL2SequencerUptimeFeed", + "outputs": [ + { + "internalType": "contract IChainlinkAggregatorLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "proposalData", "type": "bytes" } + ], + "name": "decodeProposalData", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "token0Denominator", + "type": "bool" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.Proposal", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.ProposalValues", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "token0Denominator", + "type": "bool" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.Proposal", + "name": "proposal", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.ProposalValues", + "name": "proposalValues", + "type": "tuple" + } + ], + "name": "encodeProposalData", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "creditAddress", "type": "address" }, + { "internalType": "uint256", "name": "collateralId", "type": "uint256" }, + { "internalType": "bool", "name": "token0Denominator", "type": "bool" }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { "internalType": "bool[]", "name": "feedInvertFlags", "type": "bool[]" }, + { "internalType": "uint256", "name": "loanToValue", "type": "uint256" } + ], + "name": "getCreditAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "multiproposalMerkleRoot", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoanProposal.Multiproposal", + "name": "multiproposal", + "type": "tuple" + } + ], + "name": "getMultiproposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "token0Denominator", + "type": "bool" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "getProposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "token0Denominator", + "type": "bool" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPIndividualProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "makeProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "proposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "revokeNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapNFTPositionManager", + "outputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapV3Factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilizedCredit", + "outputs": [ + { + "internalType": "contract PWNUtilizedCredit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/abis/SimpleLoanUniswapV3LPSetProposal.json b/packages/subgraph/abis/SimpleLoanUniswapV3LPSetProposal.json new file mode 100644 index 00000000..c487a89c --- /dev/null +++ b/packages/subgraph/abis/SimpleLoanUniswapV3LPSetProposal.json @@ -0,0 +1,1101 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_hub", "type": "address" }, + { "internalType": "address", "name": "_revokedNonce", "type": "address" }, + { "internalType": "address", "name": "_config", "type": "address" }, + { + "internalType": "address", + "name": "_utilizedCredit", + "type": "address" + }, + { + "internalType": "address", + "name": "_uniswapV3Factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_uniswapNFTPositionManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkFeedRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkL2SequencerUptimeFeed", + "type": "address" + }, + { "internalType": "address", "name": "_weth", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "AcceptorIsProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "bytes32", "name": "tag", "type": "bytes32" } + ], + "name": "AddressMissingHubTag", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "CallerIsNotStatedProposer", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "address", "name": "loanContract", "type": "address" } + ], + "name": "CallerNotLoanContract", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" } + ], + "name": "ChainlinkFeedPriceTooOld", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "int256", "name": "price", "type": "int256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" } + ], + "name": "ChainlinkFeedReturnedNegativePrice", + "type": "error" + }, + { "inputs": [], "name": "ChainlinkInvalidInputLenghts", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "CreditAmountOutOfBounds", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "defaultDate", "type": "uint32" }, + { "internalType": "uint32", "name": "current", "type": "uint32" } + ], + "name": "DefaultDateInPast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expiration", "type": "uint256" } + ], + "name": "Expired", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "timeSinceUp", "type": "uint256" }, + { "internalType": "uint256", "name": "gracePeriod", "type": "uint256" } + ], + "name": "GracePeriodNotOver", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "IntermediaryDenominationsOutOfBounds", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + } + ], + "name": "InvalidAcceptorController", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "current", "type": "bytes32" }, + { "internalType": "bytes32", "name": "proposed", "type": "bytes32" } + ], + "name": "InvalidCollateralStateFingerprint", + "type": "error" + }, + { "inputs": [], "name": "InvalidLPTokenPair", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + } + ], + "name": "InvalidRefinancingLoanId", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "signer", "type": "address" }, + { "internalType": "bytes32", "name": "digest", "type": "bytes32" } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { "inputs": [], "name": "L2SequencerDown", "type": "error" }, + { "inputs": [], "name": "MinCreditAmountNotSet", "type": "error" }, + { "inputs": [], "name": "MissingStateFingerprintComputer", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "NonceNotUsable", + "type": "error" + }, + { "inputs": [], "name": "T", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "proposalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "components": [ + { + "internalType": "address[]", + "name": "tokenAAllowlist", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokenBAllowlist", + "type": "address[]" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "ProposalMade", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOAN_TO_VALUE_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_INTERMEDIARY_DENOMINATIONS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "acceptor", "type": "address" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { "internalType": "bytes", "name": "proposalData", "type": "bytes" }, + { + "internalType": "bytes32[]", + "name": "proposalInclusionProof", + "type": "bytes32[]" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "acceptProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "address", "name": "lender", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint32", "name": "duration", "type": "uint32" }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "collateral", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum MultiToken.Category", + "name": "category", + "type": "uint8" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct MultiToken.Asset", + "name": "credit", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "bytes32", + "name": "lenderSpecHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "borrowerSpecHash", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoan.Terms", + "name": "loanTerms", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkFeedRegistry", + "outputs": [ + { + "internalType": "contract IChainlinkFeedRegistryLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkL2SequencerUptimeFeed", + "outputs": [ + { + "internalType": "contract IChainlinkAggregatorLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { "internalType": "contract PWNConfig", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "proposalData", "type": "bytes" } + ], + "name": "decodeProposalData", + "outputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "tokenAAllowlist", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokenBAllowlist", + "type": "address[]" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.Proposal", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.ProposalValues", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "tokenAAllowlist", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokenBAllowlist", + "type": "address[]" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.Proposal", + "name": "proposal", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creditAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.ProposalValues", + "name": "proposalValues", + "type": "tuple" + } + ], + "name": "encodeProposalData", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "creditAddress", "type": "address" }, + { "internalType": "uint256", "name": "collateralId", "type": "uint256" }, + { "internalType": "bool", "name": "token0Denominator", "type": "bool" }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { "internalType": "bool[]", "name": "feedInvertFlags", "type": "bool[]" }, + { "internalType": "uint256", "name": "loanToValue", "type": "uint256" } + ], + "name": "getCreditAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "multiproposalMerkleRoot", + "type": "bytes32" + } + ], + "internalType": "struct PWNSimpleLoanProposal.Multiproposal", + "name": "multiproposal", + "type": "tuple" + } + ], + "name": "getMultiproposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "tokenAAllowlist", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokenBAllowlist", + "type": "address[]" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "getProposalHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract PWNHub", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "tokenAAllowlist", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokenBAllowlist", + "type": "address[]" + }, + { + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "feedIntermediaryDenominations", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "feedInvertFlags", + "type": "bool[]" + }, + { + "internalType": "uint256", + "name": "loanToValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCreditAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableCreditLimit", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "utilizedCreditId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "fixedInterestAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "accruingInterestAPR", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "durationOrDate", + "type": "uint32" + }, + { "internalType": "uint40", "name": "expiration", "type": "uint40" }, + { + "internalType": "address", + "name": "acceptorController", + "type": "address" + }, + { + "internalType": "bytes", + "name": "acceptorControllerData", + "type": "bytes" + }, + { "internalType": "address", "name": "proposer", "type": "address" }, + { + "internalType": "bytes32", + "name": "proposerSpecHash", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isOffer", "type": "bool" }, + { + "internalType": "uint256", + "name": "refinancingLoanId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonceSpace", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { + "internalType": "address", + "name": "loanContract", + "type": "address" + } + ], + "internalType": "struct PWNSimpleLoanUniswapV3LPSetProposal.Proposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "makeProposal", + "outputs": [ + { "internalType": "bytes32", "name": "proposalHash", "type": "bytes32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "proposalsMade", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nonceSpace", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" } + ], + "name": "revokeNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokedNonce", + "outputs": [ + { + "internalType": "contract PWNRevokedNonce", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapNFTPositionManager", + "outputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapV3Factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilizedCredit", + "outputs": [ + { + "internalType": "contract PWNUtilizedCredit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/subgraph/config/mainnet.json b/packages/subgraph/config/mainnet.json index c27e4248..12a28b95 100644 --- a/packages/subgraph/config/mainnet.json +++ b/packages/subgraph/config/mainnet.json @@ -39,5 +39,10 @@ "MultiTokenCategoryRegistry": { "address": "0xbB2168d5546A94AE2DA9254e63D88F7f137B2534", "startBlock": 20047106 + }, + "sepolia": { + "SimpleLoanUniswapV3LPSetProposal": { + "address": "0x7b48798CE8e95f1412078cF2e1a176CA12839AfA" + } } } \ No newline at end of file diff --git a/packages/subgraph/config/sepolia.json b/packages/subgraph/config/sepolia.json index bb3c6f67..e6353bb7 100644 --- a/packages/subgraph/config/sepolia.json +++ b/packages/subgraph/config/sepolia.json @@ -39,5 +39,13 @@ "MultiTokenCategoryRegistry": { "address": "0xbB2168d5546A94AE2DA9254e63D88F7f137B2534", "startBlock": 5953672 + }, + "SimpleLoanUniswapV3LPIndividualProposal": { + "address": "0xF966696BE0623447679AC830FC5bB7bDB15FEAB4", + "startBlock": 8518575 + }, + "SimpleLoanUniswapV3LPSetProposal": { + "address": "0x7b48798CE8e95f1412078cF2e1a176CA12839AfA", + "startBlock": 8518575 } } \ No newline at end of file diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 90cb3aa9..1ee77cfa 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -41,6 +41,8 @@ type Loan @entity(immutable: false) { # Loan ID from contract event loanId: BigInt! + + proposal: Proposal # Proposal contract address proposalContract: Bytes! @@ -92,64 +94,277 @@ type Loan @entity(immutable: false) { # TODO also add Loan contract version? } +enum ProposalStatus { + # TODO can we even handle statuses aother than Active? + Active + Revoked + Expired + Accepted +} + +enum ProposalType { + Simple + List + Elastic + ElasticChainlink + UniswapV3LPIndividual + UniswapV3LPSet +} + +# TODO do interface for common proposal base fields??? + +# TODO how can we mark this proposal as revoked when a nonce is revoked? +type Proposal @entity(immutable: true) { + id: Bytes! # proposal hash + proposer: Bytes! # address + createdAt: BigInt! + + # Proposal type discriminator + proposalType: ProposalType! + + # Common fields for all proposal types + credit: Asset! + fixedInterestAmount: BigInt! + accruingInterestAPR: Int! + availableCreditLimit: BigInt! + utilizedCreditId: Bytes! + durationOrDate: BigInt! + expiration: BigInt! + proposerSpecHash: Bytes! + isOffer: Boolean! + refinancingLoanId: BigInt! + nonceSpace: BigInt! + nonce: BigInt! + loanContract: Bytes! + status: ProposalStatus! + blockNumber: BigInt! + transactionHash: Bytes! + loans: [Loan!]! @derivedFrom(field: "proposal") + + # Simple proposal specific fields (ProposalType.Simple) + # - collateral: Asset (active) + # - collateralAmount: BigInt (active) + # - creditAmount: BigInt (active) + # - allowedAcceptor: Bytes (active) + # - checkCollateralStateFingerprint: Boolean (active) + # - collateralStateFingerprint: Bytes (active) + collateral: Asset + collateralAmount: BigInt + creditAmount: BigInt + allowedAcceptor: Bytes + checkCollateralStateFingerprint: Boolean + collateralStateFingerprint: Bytes + + # List proposal specific fields (ProposalType.List) + # - collateral: Asset (shared with Simple) + # - collateralAmount: BigInt (shared with Simple) + # - creditAmount: BigInt (shared with Simple) + # - allowedAcceptor: Bytes (shared with Simple) + # - checkCollateralStateFingerprint: Boolean (shared with Simple) + # - collateralStateFingerprint: Bytes (shared with Simple) + # - collateralIdsWhitelistMerkleRoot: Bytes (active) + collateralIdsWhitelistMerkleRoot: Bytes + + # Elastic proposal specific fields (ProposalType.Elastic) + # - collateral: Asset (shared, but uses collateralId instead of full Asset) + # - checkCollateralStateFingerprint: Boolean (shared) + # - collateralStateFingerprint: Bytes (shared) + # - creditPerCollateralUnit: BigInt (active) + # - minCreditAmount: BigInt (active) + # - allowedAcceptor: Bytes (shared) + creditPerCollateralUnit: BigInt + minCreditAmount: BigInt + + # Elastic Chainlink proposal specific fields (ProposalType.ElasticChainlink) + # - collateral: Asset (shared, but uses collateralId) + # - checkCollateralStateFingerprint: Boolean (shared) + # - collateralStateFingerprint: Bytes (shared) + # - feedIntermediaryDenominations: [Bytes!] (active) + # - feedInvertFlags: [Boolean!] (active) + # - loanToValue: BigInt (active) + # - minCreditAmount: BigInt (shared with Elastic) + # - allowedAcceptor: Bytes (shared) + feedIntermediaryDenominations: [Bytes!] + feedInvertFlags: [Boolean!] + loanToValue: BigInt + + # Uniswap V3 LP Individual proposal specific fields (ProposalType.UniswapV3LPIndividual) + # - collateralId: BigInt (active) + # - token0Denominator: Boolean (active) + # - feedIntermediaryDenominations: [Bytes!] (shared with ElasticChainlink) + # - feedInvertFlags: [Boolean!] (shared with ElasticChainlink) + # - loanToValue: BigInt (shared with ElasticChainlink) + # - minCreditAmount: BigInt (shared) + # - acceptorController: Bytes (active) + # - acceptorControllerData: Bytes (active) + collateralId: BigInt + token0Denominator: Boolean + acceptorController: Bytes + acceptorControllerData: Bytes + + # Uniswap V3 LP Set proposal specific fields (ProposalType.UniswapV3LPSet) + # - tokenAAllowlist: [Bytes!] (active) + # - tokenBAllowlist: [Bytes!] (active) + # - feedIntermediaryDenominations: [Bytes!] (shared with ElasticChainlink) + # - feedInvertFlags: [Boolean!] (shared with ElasticChainlink) + # - loanToValue: BigInt (shared with ElasticChainlink) + # - minCreditAmount: BigInt (shared) + # - acceptorController: Bytes (shared with UniswapV3LPIndividual) + # - acceptorControllerData: Bytes (shared with UniswapV3LPIndividual) + tokenAAllowlist: [Bytes!] + tokenBAllowlist: [Bytes!] + + # Direct reference to the raw event entity for easy function calls + rawEventSimple: SimpleLoanSimpleProposalMade + rawEventList: SimpleLoanListProposalProposalMade + rawEventElastic: SimpleLoanElasticProposalProposalMade + rawEventElasticChainlink: SimpleLoanElasticChainlinkProposalProposalMade + rawEventUniswapV3LPIndividual: SimpleLoanUniswapV3LPIndividualProposalProposalMade + rawEventUniswapV3LPSet: SimpleLoanUniswapV3LPSetProposalProposalMade +} + # TODO add version -type ProposalMade @entity(immutable: true) { +type SimpleLoanSimpleProposalMade @entity(immutable: true) { + id: Bytes! + proposalHash: Bytes! # bytes32 + proposer: Bytes! # address + + # Reference to the unified Proposal entity + proposal: Proposal! + + # Raw proposal parameters (for easy extraction to function calls) + collateralCategory: Int! # uint8 + collateralAddress: Bytes! # address + collateralId: BigInt! # uint256 + collateralAmount: BigInt! # uint256 + checkCollateralStateFingerprint: Boolean! # bool + collateralStateFingerprint: Bytes! # bytes32 + creditAddress: Bytes! # address + creditAmount: BigInt! # uint256 + availableCreditLimit: BigInt! # uint256 + utilizedCreditId: Bytes! # bytes32 + fixedInterestAmount: BigInt! # uint256 + accruingInterestAPR: Int! # uint24 + durationOrDate: BigInt! # uint32 + expiration: BigInt! # uint40 + allowedAcceptor: Bytes! # address + proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) + proposerSpecHash: Bytes! # bytes32 + isOffer: Boolean! # bool + refinancingLoanId: BigInt! # uint256 + nonceSpace: BigInt! # uint256 + nonce: BigInt! # uint256 + loanContract: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type SimpleLoanUniswapV3LPIndividualProposalProposalMade + @entity(immutable: true) { + id: Bytes! + proposalHash: Bytes! # bytes32 + proposer: Bytes! # address + + # Reference to the unified Proposal entity + proposal: Proposal! + + # Raw proposal parameters (for easy extraction to function calls) + collateralId: BigInt! # uint256 + token0Denominator: Boolean! # bool + creditAddress: Bytes! # address + feedIntermediaryDenominations: [Bytes!]! # address[] + feedInvertFlags: [Boolean!]! # bool[] + loanToValue: BigInt! # uint256 + minCreditAmount: BigInt! # uint256 + availableCreditLimit: BigInt! # uint256 + utilizedCreditId: Bytes! # bytes32 + fixedInterestAmount: BigInt! # uint256 + accruingInterestAPR: Int! # uint24 + durationOrDate: BigInt! # uint32 + expiration: BigInt! # uint40 + acceptorController: Bytes! # address + acceptorControllerData: Bytes! # bytes + proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) + proposerSpecHash: Bytes! # bytes32 + isOffer: Boolean! # bool + refinancingLoanId: BigInt! # uint256 + nonceSpace: BigInt! # uint256 + nonce: BigInt! # uint256 + loanContract: Bytes! # address + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type SimpleLoanUniswapV3LPSetProposalProposalMade @entity(immutable: true) { id: Bytes! proposalHash: Bytes! # bytes32 proposer: Bytes! # address - proposal_collateralCategory: Int! # uint8 - proposal_collateralAddress: Bytes! # address - proposal_collateralId: BigInt! # uint256 - proposal_collateralAmount: BigInt! # uint256 - proposal_checkCollateralStateFingerprint: Boolean! # bool - proposal_collateralStateFingerprint: Bytes! # bytes32 - proposal_creditAddress: Bytes! # address - proposal_creditAmount: BigInt! # uint256 - proposal_availableCreditLimit: BigInt! # uint256 - proposal_utilizedCreditId: Bytes! # bytes32 - proposal_fixedInterestAmount: BigInt! # uint256 - proposal_accruingInterestAPR: Int! # uint24 - proposal_durationOrDate: BigInt! # uint32 - proposal_expiration: BigInt! # uint40 - proposal_allowedAcceptor: Bytes! # address - proposal_proposer: Bytes! # address - proposal_proposerSpecHash: Bytes! # bytes32 - proposal_isOffer: Boolean! # bool - proposal_refinancingLoanId: BigInt! # uint256 - proposal_nonceSpace: BigInt! # uint256 - proposal_nonce: BigInt! # uint256 - proposal_loanContract: Bytes! # address + + # Reference to the unified Proposal entity + proposal: Proposal! + + # Raw proposal parameters (for easy extraction to function calls) + tokenAAllowlist: [Bytes!]! # address[] + tokenBAllowlist: [Bytes!]! # address[] + creditAddress: Bytes! # address + feedIntermediaryDenominations: [Bytes!]! # address[] + feedInvertFlags: [Boolean!]! # bool[] + loanToValue: BigInt! # uint256 + minCreditAmount: BigInt! # uint256 + availableCreditLimit: BigInt! # uint256 + utilizedCreditId: Bytes! # bytes32 + fixedInterestAmount: BigInt! # uint256 + accruingInterestAPR: Int! # uint24 + durationOrDate: BigInt! # uint32 + expiration: BigInt! # uint40 + acceptorController: Bytes! # address + acceptorControllerData: Bytes! # bytes + proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) + proposerSpecHash: Bytes! # bytes32 + isOffer: Boolean! # bool + refinancingLoanId: BigInt! # uint256 + nonceSpace: BigInt! # uint256 + nonce: BigInt! # uint256 + loanContract: Bytes! # address blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! } + type SimpleLoanListProposalProposalMade @entity(immutable: true) { id: Bytes! proposalHash: Bytes! # bytes32 proposer: Bytes! # address - proposal_collateralCategory: Int! # uint8 - proposal_collateralAddress: Bytes! # address - proposal_collateralIdsWhitelistMerkleRoot: Bytes! # bytes32 - proposal_collateralAmount: BigInt! # uint256 - proposal_checkCollateralStateFingerprint: Boolean! # bool - proposal_collateralStateFingerprint: Bytes! # bytes32 - proposal_creditAddress: Bytes! # address - proposal_creditAmount: BigInt! # uint256 - proposal_availableCreditLimit: BigInt! # uint256 - proposal_utilizedCreditId: Bytes! # bytes32 - proposal_fixedInterestAmount: BigInt! # uint256 - proposal_accruingInterestAPR: Int! # uint24 - proposal_durationOrDate: BigInt! # uint32 - proposal_expiration: BigInt! # uint40 - proposal_allowedAcceptor: Bytes! # address - proposal_proposer: Bytes! # address - proposal_proposerSpecHash: Bytes! # bytes32 - proposal_isOffer: Boolean! # bool - proposal_refinancingLoanId: BigInt! # uint256 - proposal_nonceSpace: BigInt! # uint256 - proposal_nonce: BigInt! # uint256 - proposal_loanContract: Bytes! # address + + # Reference to the unified Proposal entity + proposal: Proposal! + + # Raw proposal parameters (for easy extraction to function calls) + collateralCategory: Int! # uint8 + collateralAddress: Bytes! # address + collateralIdsWhitelistMerkleRoot: Bytes! # bytes32 + collateralAmount: BigInt! # uint256 + checkCollateralStateFingerprint: Boolean! # bool + collateralStateFingerprint: Bytes! # bytes32 + creditAddress: Bytes! # address + creditAmount: BigInt! # uint256 + availableCreditLimit: BigInt! # uint256 + utilizedCreditId: Bytes! # bytes32 + fixedInterestAmount: BigInt! # uint256 + accruingInterestAPR: Int! # uint24 + durationOrDate: BigInt! # uint32 + expiration: BigInt! # uint40 + allowedAcceptor: Bytes! # address + proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) + proposerSpecHash: Bytes! # bytes32 + isOffer: Boolean! # bool + refinancingLoanId: BigInt! # uint256 + nonceSpace: BigInt! # uint256 + nonce: BigInt! # uint256 + loanContract: Bytes! # address blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! @@ -158,28 +373,33 @@ type SimpleLoanElasticProposalProposalMade @entity(immutable: true) { id: Bytes! proposalHash: Bytes! # bytes32 proposer: Bytes! # address - proposal_collateralCategory: Int! # uint8 - proposal_collateralAddress: Bytes! # address - proposal_collateralId: BigInt! # uint256 - proposal_checkCollateralStateFingerprint: Boolean! # bool - proposal_collateralStateFingerprint: Bytes! # bytes32 - proposal_creditAddress: Bytes! # address - proposal_creditPerCollateralUnit: BigInt! # uint256 - proposal_minCreditAmount: BigInt! # uint256 - proposal_availableCreditLimit: BigInt! # uint256 - proposal_utilizedCreditId: Bytes! # bytes32 - proposal_fixedInterestAmount: BigInt! # uint256 - proposal_accruingInterestAPR: Int! # uint24 - proposal_durationOrDate: BigInt! # uint32 - proposal_expiration: BigInt! # uint40 - proposal_allowedAcceptor: Bytes! # address - proposal_proposer: Bytes! # address - proposal_proposerSpecHash: Bytes! # bytes32 - proposal_isOffer: Boolean! # bool - proposal_refinancingLoanId: BigInt! # uint256 - proposal_nonceSpace: BigInt! # uint256 - proposal_nonce: BigInt! # uint256 - proposal_loanContract: Bytes! # address + + # Reference to the unified Proposal entity + proposal: Proposal! + + # Raw proposal parameters (for easy extraction to function calls) + collateralCategory: Int! # uint8 + collateralAddress: Bytes! # address + collateralId: BigInt! # uint256 + checkCollateralStateFingerprint: Boolean! # bool + collateralStateFingerprint: Bytes! # bytes32 + creditAddress: Bytes! # address + creditPerCollateralUnit: BigInt! # uint256 + minCreditAmount: BigInt! # uint256 + availableCreditLimit: BigInt! # uint256 + utilizedCreditId: Bytes! # bytes32 + fixedInterestAmount: BigInt! # uint256 + accruingInterestAPR: Int! # uint24 + durationOrDate: BigInt! # uint32 + expiration: BigInt! # uint40 + allowedAcceptor: Bytes! # address + proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) + proposerSpecHash: Bytes! # bytes32 + isOffer: Boolean! # bool + refinancingLoanId: BigInt! # uint256 + nonceSpace: BigInt! # uint256 + nonce: BigInt! # uint256 + loanContract: Bytes! # address blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! @@ -188,30 +408,35 @@ type SimpleLoanElasticChainlinkProposalProposalMade @entity(immutable: true) { id: Bytes! proposalHash: Bytes! # bytes32 proposer: Bytes! # address - proposal_collateralCategory: Int! # uint8 - proposal_collateralAddress: Bytes! # address - proposal_collateralId: BigInt! # uint256 - proposal_checkCollateralStateFingerprint: Boolean! # bool - proposal_collateralStateFingerprint: Bytes! # bytes32 - proposal_creditAddress: Bytes! # address - proposal_feedIntermediaryDenominations: [Bytes!]! # address[] - proposal_feedInvertFlags: [Boolean!]! # bool[] - proposal_loanToValue: BigInt! # uint256 - proposal_minCreditAmount: BigInt! # uint256 - proposal_availableCreditLimit: BigInt! # uint256 - proposal_utilizedCreditId: Bytes! # bytes32 - proposal_fixedInterestAmount: BigInt! # uint256 - proposal_accruingInterestAPR: Int! # uint24 - proposal_durationOrDate: BigInt! # uint32 - proposal_expiration: BigInt! # uint40 - proposal_allowedAcceptor: Bytes! # address - proposal_proposer: Bytes! # address - proposal_proposerSpecHash: Bytes! # bytes32 - proposal_isOffer: Boolean! # bool - proposal_refinancingLoanId: BigInt! # uint256 - proposal_nonceSpace: BigInt! # uint256 - proposal_nonce: BigInt! # uint256 - proposal_loanContract: Bytes! # address + + # Reference to the unified Proposal entity + proposal: Proposal! + + # Raw proposal parameters (for easy extraction to function calls) + collateralCategory: Int! # uint8 + collateralAddress: Bytes! # address + collateralId: BigInt! # uint256 + checkCollateralStateFingerprint: Boolean! # bool + collateralStateFingerprint: Bytes! # bytes32 + creditAddress: Bytes! # address + feedIntermediaryDenominations: [Bytes!]! # address[] + feedInvertFlags: [Boolean!]! # bool[] + loanToValue: BigInt! # uint256 + minCreditAmount: BigInt! # uint256 + availableCreditLimit: BigInt! # uint256 + utilizedCreditId: Bytes! # bytes32 + fixedInterestAmount: BigInt! # uint256 + accruingInterestAPR: Int! # uint24 + durationOrDate: BigInt! # uint32 + expiration: BigInt! # uint40 + allowedAcceptor: Bytes! # address + proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) + proposerSpecHash: Bytes! # bytes32 + isOffer: Boolean! # bool + refinancingLoanId: BigInt! # uint256 + nonceSpace: BigInt! # uint256 + nonce: BigInt! # uint256 + loanContract: Bytes! # address blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! @@ -236,41 +461,11 @@ type ExtensionProposal @entity(immutable: true) { createdAt: BigInt! } -type LOANClaimed @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - defaulted: Boolean! # bool - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - -type LOANCreated @entity(immutable: true) { +type ChainlinkFeed @entity(immutable: true) { id: Bytes! - loanId: BigInt! # uint256 - proposalHash: Bytes! # bytes32 - proposalContract: Bytes! # address - refinancingLoanId: BigInt! # uint256 - terms_lender: Bytes! # address - terms_borrower: Bytes! # address - terms_duration: BigInt! # uint32 - terms_collateral_category: Int! # uint8 - terms_collateral_assetAddress: Bytes! # address - terms_collateral_id: BigInt! # uint256 - terms_collateral_amount: BigInt! # uint256 - terms_credit_category: Int! # uint8 - terms_credit_assetAddress: Bytes! # address - terms_credit_id: BigInt! # uint256 - terms_credit_amount: BigInt! # uint256 - terms_fixedInterestAmount: BigInt! # uint256 - terms_accruingInterestAPR: Int! # uint24 - terms_lenderSpecHash: Bytes! # bytes32 - terms_borrowerSpecHash: Bytes! # bytes32 - lenderSpec_sourceOfFunds: Bytes! # address - extra: Bytes! # bytes - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! + asset: Bytes! # address + denomination: Bytes! # address + aggregator: Bytes! # feed address } type LOANExtended @entity(immutable: true) { @@ -283,14 +478,6 @@ type LOANExtended @entity(immutable: true) { transactionHash: Bytes! } -type LOANPaidBack @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} - type LoanTokenTransfer @entity(immutable: true) { id: Bytes! from: Bytes! # address @@ -311,52 +498,93 @@ type TagSet @entity(immutable: true) { transactionHash: Bytes! } -type DefaultLOANMetadataUriUpdated @entity(immutable: true) { - id: Bytes! - newUri: String! # string - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} +# ============================== +# TO REMOVE??? +# ============================== -type FeeCollectorUpdated @entity(immutable: true) { +type LOANPaidBack @entity(immutable: true) { id: Bytes! - oldFeeCollector: Bytes! # address - newFeeCollector: Bytes! # address + loanId: BigInt! # uint256 blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! } -type FeeUpdated @entity(immutable: true) { +type LOANClaimed @entity(immutable: true) { id: Bytes! - oldFee: Int! # uint16 - newFee: Int! # uint16 + loanId: BigInt! # uint256 + defaulted: Boolean! # bool blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! } -type LOANMetadataUriUpdated @entity(immutable: true) { +type LOANCreated @entity(immutable: true) { id: Bytes! - loanContract: Bytes! # address - newUri: String! # string + loanId: BigInt! # uint256 + proposalHash: Bytes! # bytes32 + proposalContract: Bytes! # address + refinancingLoanId: BigInt! # uint256 + terms_lender: Bytes! # address + terms_borrower: Bytes! # address + terms_duration: BigInt! # uint32 + terms_collateral_category: Int! # uint8 + terms_collateral_assetAddress: Bytes! # address + terms_collateral_id: BigInt! # uint256 + terms_collateral_amount: BigInt! # uint256 + terms_credit_category: Int! # uint8 + terms_credit_assetAddress: Bytes! # address + terms_credit_id: BigInt! # uint256 + terms_credit_amount: BigInt! # uint256 + terms_fixedInterestAmount: BigInt! # uint256 + terms_accruingInterestAPR: Int! # uint24 + terms_lenderSpecHash: Bytes! # bytes32 + terms_borrowerSpecHash: Bytes! # bytes32 + lenderSpec_sourceOfFunds: Bytes! # address + extra: Bytes! # bytes blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! } -type ChainlinkFeed @entity(immutable: true) { - id: Bytes! - asset: Bytes! # address - denomination: Bytes! # address - aggregator: Bytes! # feed address -} - # =============================== # UNUSED ENTITIES # =============================== +# type DefaultLOANMetadataUriUpdated @entity(immutable: true) { +# id: Bytes! +# newUri: String! # string +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type FeeCollectorUpdated @entity(immutable: true) { +# id: Bytes! +# oldFeeCollector: Bytes! # address +# newFeeCollector: Bytes! # address +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type FeeUpdated @entity(immutable: true) { +# id: Bytes! +# oldFee: Int! # uint16 +# newFee: Int! # uint16 +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } + +# type LOANMetadataUriUpdated @entity(immutable: true) { +# id: Bytes! +# loanContract: Bytes! # address +# newUri: String! # string +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } # type LOANBurned @entity(immutable: true) { # id: Bytes! # loanId: BigInt! # uint256 diff --git a/packages/subgraph/src/chainlink-feed-registry.ts b/packages/subgraph/src/chainlink-feed-registry.ts index f00fced2..7bc58b8e 100644 --- a/packages/subgraph/src/chainlink-feed-registry.ts +++ b/packages/subgraph/src/chainlink-feed-registry.ts @@ -12,7 +12,7 @@ function getChainlinkFeedId(event: FeedConfirmedEvent): Bytes { export function handleFeedConfirmed(event: FeedConfirmedEvent): void { const chainlinkFeedId = getChainlinkFeedId(event) - const chainlinkFeed = ChainlinkFeed.load(chainlinkFeedId) + let chainlinkFeed = ChainlinkFeed.load(chainlinkFeedId) if (chainlinkFeed == null) { chainlinkFeed = new ChainlinkFeed(chainlinkFeedId) } diff --git a/packages/subgraph/src/config.ts b/packages/subgraph/src/config.ts index 810a804a..28bec137 100644 --- a/packages/subgraph/src/config.ts +++ b/packages/subgraph/src/config.ts @@ -1,170 +1,164 @@ -import { - AdminChanged as AdminChangedEvent, - BeaconUpgraded as BeaconUpgradedEvent, - Upgraded as UpgradedEvent, - DefaultLOANMetadataUriUpdated as DefaultLOANMetadataUriUpdatedEvent, - FeeCollectorUpdated as FeeCollectorUpdatedEvent, - FeeUpdated as FeeUpdatedEvent, - Initialized as InitializedEvent, - LOANMetadataUriUpdated as LOANMetadataUriUpdatedEvent, - OwnershipTransferStarted as OwnershipTransferStartedEvent, - OwnershipTransferred as OwnershipTransferredEvent, -} from "../generated/Config/Config" -import { - AdminChanged, - BeaconUpgraded, - Upgraded, - DefaultLOANMetadataUriUpdated, - FeeCollectorUpdated, - FeeUpdated, - Initialized, - LOANMetadataUriUpdated, - OwnershipTransferStarted, - OwnershipTransferred, -} from "../generated/schema" - -export function handleAdminChanged(event: AdminChangedEvent): void { - const entity = new AdminChanged( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousAdmin = event.params.previousAdmin - entity.newAdmin = event.params.newAdmin - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleBeaconUpgraded(event: BeaconUpgradedEvent): void { - const entity = new BeaconUpgraded( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.beacon = event.params.beacon - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleUpgraded(event: UpgradedEvent): void { - const entity = new Upgraded( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.implementation = event.params.implementation - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleDefaultLOANMetadataUriUpdated( - event: DefaultLOANMetadataUriUpdatedEvent, -): void { - const entity = new DefaultLOANMetadataUriUpdated( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.newUri = event.params.newUri - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleFeeCollectorUpdated( - event: FeeCollectorUpdatedEvent, -): void { - const entity = new FeeCollectorUpdated( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.oldFeeCollector = event.params.oldFeeCollector - entity.newFeeCollector = event.params.newFeeCollector - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleFeeUpdated(event: FeeUpdatedEvent): void { - const entity = new FeeUpdated( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.oldFee = event.params.oldFee - entity.newFee = event.params.newFee - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleInitialized(event: InitializedEvent): void { - const entity = new Initialized( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.version = event.params.version - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleLOANMetadataUriUpdated( - event: LOANMetadataUriUpdatedEvent, -): void { - const entity = new LOANMetadataUriUpdated( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.loanContract = event.params.loanContract - entity.newUri = event.params.newUri - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleOwnershipTransferStarted( - event: OwnershipTransferStartedEvent, -): void { - const entity = new OwnershipTransferStarted( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousOwner = event.params.previousOwner - entity.newOwner = event.params.newOwner - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleOwnershipTransferred( - event: OwnershipTransferredEvent, -): void { - const entity = new OwnershipTransferred( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousOwner = event.params.previousOwner - entity.newOwner = event.params.newOwner - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} +// import { +// AdminChanged as AdminChangedEvent, +// BeaconUpgraded as BeaconUpgradedEvent, +// Upgraded as UpgradedEvent, +// DefaultLOANMetadataUriUpdated as DefaultLOANMetadataUriUpdatedEvent, +// FeeCollectorUpdated as FeeCollectorUpdatedEvent, +// FeeUpdated as FeeUpdatedEvent, +// Initialized as InitializedEvent, +// LOANMetadataUriUpdated as LOANMetadataUriUpdatedEvent, +// OwnershipTransferStarted as OwnershipTransferStartedEvent, +// OwnershipTransferred as OwnershipTransferredEvent, +// } from "../generated/Config/Config" +// import { +// DefaultLOANMetadataUriUpdated, +// FeeCollectorUpdated, +// FeeUpdated, +// LOANMetadataUriUpdated, +// } from "../generated/schema" + +// export function handleAdminChanged(event: AdminChangedEvent): void { +// const entity = new AdminChanged( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.previousAdmin = event.params.previousAdmin +// entity.newAdmin = event.params.newAdmin + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleBeaconUpgraded(event: BeaconUpgradedEvent): void { +// const entity = new BeaconUpgraded( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.beacon = event.params.beacon + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleUpgraded(event: UpgradedEvent): void { +// const entity = new Upgraded( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.implementation = event.params.implementation + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleDefaultLOANMetadataUriUpdated( +// event: DefaultLOANMetadataUriUpdatedEvent, +// ): void { +// const entity = new DefaultLOANMetadataUriUpdated( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.newUri = event.params.newUri + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleFeeCollectorUpdated( +// event: FeeCollectorUpdatedEvent, +// ): void { +// const entity = new FeeCollectorUpdated( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.oldFeeCollector = event.params.oldFeeCollector +// entity.newFeeCollector = event.params.newFeeCollector + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleFeeUpdated(event: FeeUpdatedEvent): void { +// const entity = new FeeUpdated( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.oldFee = event.params.oldFee +// entity.newFee = event.params.newFee + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleInitialized(event: InitializedEvent): void { +// const entity = new Initialized( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.version = event.params.version + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleLOANMetadataUriUpdated( +// event: LOANMetadataUriUpdatedEvent, +// ): void { +// const entity = new LOANMetadataUriUpdated( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.loanContract = event.params.loanContract +// entity.newUri = event.params.newUri + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleOwnershipTransferStarted( +// event: OwnershipTransferStartedEvent, +// ): void { +// const entity = new OwnershipTransferStarted( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.previousOwner = event.params.previousOwner +// entity.newOwner = event.params.newOwner + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } + +// export function handleOwnershipTransferred( +// event: OwnershipTransferredEvent, +// ): void { +// const entity = new OwnershipTransferred( +// event.transaction.hash.concatI32(event.logIndex.toI32()), +// ) +// entity.previousOwner = event.params.previousOwner +// entity.newOwner = event.params.newOwner + +// entity.blockNumber = event.block.number +// entity.blockTimestamp = event.block.timestamp +// entity.transactionHash = event.transaction.hash + +// entity.save() +// } diff --git a/packages/subgraph/src/entity-helpers/get-or-create.ts b/packages/subgraph/src/entity-helpers/get-or-create.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/subgraph/src/entity-helpers/ids.ts b/packages/subgraph/src/entity-helpers/ids.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/subgraph/src/helpers.ts b/packages/subgraph/src/helpers.ts new file mode 100644 index 00000000..2311f205 --- /dev/null +++ b/packages/subgraph/src/helpers.ts @@ -0,0 +1,20 @@ +import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts"; +import { Account } from "../generated/schema"; + +// TODO add logs where applicable +export function getOrCreateAccount(address: Address): Account { + let account = Account.load(address); + if (account == null) { + account = new Account(address); + account.save(); + } + return account; +} + +export function getAssetContractId(assetAddress: Address): Bytes { + return assetAddress; +} + +export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes { + return assetAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(assetId))); +} diff --git a/packages/subgraph/src/hub.ts b/packages/subgraph/src/hub.ts index 2f908fc1..3f305f04 100644 --- a/packages/subgraph/src/hub.ts +++ b/packages/subgraph/src/hub.ts @@ -1,46 +1,10 @@ import { - OwnershipTransferStarted as OwnershipTransferStartedEvent, - OwnershipTransferred as OwnershipTransferredEvent, TagSet as TagSetEvent, } from "../generated/Hub/Hub" import { - OwnershipTransferStarted, - OwnershipTransferred, TagSet, } from "../generated/schema" -export function handleOwnershipTransferStarted( - event: OwnershipTransferStartedEvent, -): void { - const entity = new OwnershipTransferStarted( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousOwner = event.params.previousOwner - entity.newOwner = event.params.newOwner - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - -export function handleOwnershipTransferred( - event: OwnershipTransferredEvent, -): void { - const entity = new OwnershipTransferred( - event.transaction.hash.concatI32(event.logIndex.toI32()), - ) - entity.previousOwner = event.params.previousOwner - entity.newOwner = event.params.newOwner - - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash - - entity.save() -} - export function handleTagSet(event: TagSetEvent): void { const entity = new TagSet( event.transaction.hash.concatI32(event.logIndex.toI32()), diff --git a/packages/subgraph/src/loan-mapping.ts b/packages/subgraph/src/loan-mapping.ts deleted file mode 100644 index 1a4a08df..00000000 --- a/packages/subgraph/src/loan-mapping.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Address, BigDecimal, BigInt, Bytes } from "@graphprotocol/graph-ts"; -import { LOANClaimed, LOANCreated, LOANPaidBack, LOANCreatedTermsCollateralStruct, LOANCreatedTermsCreditStruct, LOANExtended } from "../generated/SimpleLoan/SimpleLoan"; // Path to generated code -import { Account, Asset, Loan, AssetContract } from "../generated/schema"; - -// TODO add logs where applicable - -// Helper to get or create an Account entity -export function getOrCreateAccount(address: Address): Account { - let account = Account.load(address); - if (account == null) { - account = new Account(address); - account.save(); - } - return account; -} - -export function getAssetContractId(assetAddress: Address): Bytes { - return assetAddress; -} - -export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes { - return assetAddress.concat(Bytes.fromBigInt(assetId)); -} - -export function getOrCreateAsset(asset: LOANCreatedTermsCreditStruct): Asset { - let assetContract = AssetContract.load(getAssetContractId(asset.assetAddress)); - if (assetContract == null) { - assetContract = new AssetContract(getAssetContractId(asset.assetAddress)); - assetContract.category = asset.category; - assetContract.save(); - } - let assetResult = Asset.load(getAssetId(asset.assetAddress, asset.id)); - if (assetResult == null) { - assetResult = new Asset(getAssetId(asset.assetAddress, asset.id)); - assetResult.contract = assetContract.id; - assetResult.tokenId = asset.id; - // assetResult.amount = new BigDecimal(asset.amount); - assetResult.save(); - } - return assetResult -} - -// Updated function to handle both explicit defaults and time-based defaults -export function handleLOANClaimed(event: LOANClaimed): void { - const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; - const loan = Loan.load(loanEntityId); - if (!loan) return; - - loan.status = "Claimed"; - loan.save(); -} - -// New handler for loan extensions - this updates the default deadline -export function handleLOANExtended(event: LOANExtended): void { - const loanEntityId = `${event.address.toHex()}-${event.params.loanId.toString()}`; - const loan = Loan.load(loanEntityId); - if (!loan) return; - - // Update the duration to reflect the extension - // The new default deadline is the extendedDefaultTimestamp - const originalDeadline = loan.createdAt.plus(loan.duration); - const extensionDuration = event.params.extendedDefaultTimestamp.minus(originalDeadline); - loan.duration = loan.duration.plus(extensionDuration); - - // Update default deadline if the field is available after codegen - // loan.defaultDeadline = event.params.extendedDefaultTimestamp; - - loan.save(); -} diff --git a/packages/subgraph/src/loan-token.ts b/packages/subgraph/src/loan-token.ts index 5159916a..09531f6e 100644 --- a/packages/subgraph/src/loan-token.ts +++ b/packages/subgraph/src/loan-token.ts @@ -6,7 +6,7 @@ import { Loan, LoanTokenTransfer, } from "../generated/schema" -import { getOrCreateAccount } from "./loan-mapping" +import { getOrCreateAccount } from "./helpers" import { getLoanId } from "./simple-loan" export function handleTransfer(event: TransferEvent): void { diff --git a/packages/subgraph/src/multi-token-category-registry.ts b/packages/subgraph/src/multi-token-category-registry.ts index c28fbb65..21a8f23e 100644 --- a/packages/subgraph/src/multi-token-category-registry.ts +++ b/packages/subgraph/src/multi-token-category-registry.ts @@ -3,11 +3,11 @@ import { CategoryUnregistered as CategoryUnregisteredEvent, } from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" import { - AssetInCategory, + AssetContract, Category, } from "../generated/schema" import { store } from '@graphprotocol/graph-ts' -import { Bytes } from "@graphprotocol/graph-ts" +import { Bytes, Address } from "@graphprotocol/graph-ts" export function handleCategoryRegistered(event: CategoryRegisteredEvent): void { const categoryId = Bytes.fromI32(event.params.category) @@ -16,13 +16,13 @@ export function handleCategoryRegistered(event: CategoryRegisteredEvent): void { category = new Category(categoryId) category.save() } - let assetCategory = AssetInCategory.load(event.params.assetAddress) - if (assetCategory == null) { - assetCategory = new AssetInCategory(event.params.assetAddress) + let assetContract = AssetContract.load(event.params.assetAddress) + if (assetContract == null) { + assetContract = new AssetContract(event.params.assetAddress) } - assetCategory.category = event.params.category - assetCategory.save() + assetContract.category = category.id + assetContract.save() // TODO shall we save also the raw event? // const entity = new CategoryRegistered( @@ -41,12 +41,13 @@ export function handleCategoryRegistered(event: CategoryRegisteredEvent): void { export function handleCategoryUnregistered( event: CategoryUnregisteredEvent, ): void { - const assetInCategory = AssetInCategory.load(event.params.assetAddress) + // TODO this does not amek sense probably + const assetInCategory = AssetContract.load(event.params.assetAddress) if (assetInCategory == null) { // no need to do anything here return } - store.remove("AssetInCategory", event.params.assetAddress) + store.remove("AssetContract", event.params.assetAddress.toString()) // TODO shall we save also the raw event? // const entity = new CategoryUnregistered( diff --git a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts index 5d55f482..c2422fb5 100644 --- a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts +++ b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts @@ -1,48 +1,109 @@ import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" -import { SimpleLoanElasticChainlinkProposalProposalMade } from "../generated/schema" -import { Bytes } from "@graphprotocol/graph-ts" +import { SimpleLoanElasticChainlinkProposalProposalMade, Proposal } from "../generated/schema" +import { getOrCreateAsset } from "./utils" +import { Bytes, BigInt } from "@graphprotocol/graph-ts" export function handleProposalMade(event: ProposalMadeEvent): void { - const entity = new SimpleLoanElasticChainlinkProposalProposalMade( + // Create the specific event entity + const eventEntity = new SimpleLoanElasticChainlinkProposalProposalMade( event.transaction.hash.concatI32(event.logIndex.toI32()), ) - entity.proposalHash = event.params.proposalHash - entity.proposer = event.params.proposer - entity.proposal_collateralCategory = event.params.proposal.collateralCategory - entity.proposal_collateralAddress = event.params.proposal.collateralAddress - entity.proposal_collateralId = event.params.proposal.collateralId - entity.proposal_checkCollateralStateFingerprint = + eventEntity.proposalHash = event.params.proposalHash + eventEntity.proposer = event.params.proposer + eventEntity.collateralCategory = event.params.proposal.collateralCategory + eventEntity.collateralAddress = event.params.proposal.collateralAddress + eventEntity.collateralId = event.params.proposal.collateralId + eventEntity.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint - entity.proposal_collateralStateFingerprint = + eventEntity.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint - entity.proposal_creditAddress = event.params.proposal.creditAddress - entity.proposal_feedIntermediaryDenominations = changetype( + eventEntity.creditAddress = event.params.proposal.creditAddress + eventEntity.feedIntermediaryDenominations = changetype( event.params.proposal.feedIntermediaryDenominations, ) - entity.proposal_feedInvertFlags = event.params.proposal.feedInvertFlags - entity.proposal_loanToValue = event.params.proposal.loanToValue - entity.proposal_minCreditAmount = event.params.proposal.minCreditAmount - entity.proposal_availableCreditLimit = + eventEntity.feedInvertFlags = event.params.proposal.feedInvertFlags + eventEntity.loanToValue = event.params.proposal.loanToValue + eventEntity.minCreditAmount = event.params.proposal.minCreditAmount + eventEntity.availableCreditLimit = event.params.proposal.availableCreditLimit - entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId - entity.proposal_fixedInterestAmount = + eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId + eventEntity.fixedInterestAmount = event.params.proposal.fixedInterestAmount - entity.proposal_accruingInterestAPR = + eventEntity.accruingInterestAPR = event.params.proposal.accruingInterestAPR - entity.proposal_durationOrDate = event.params.proposal.durationOrDate - entity.proposal_expiration = event.params.proposal.expiration - entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor - entity.proposal_proposer = event.params.proposal.proposer - entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash - entity.proposal_isOffer = event.params.proposal.isOffer - entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId - entity.proposal_nonceSpace = event.params.proposal.nonceSpace - entity.proposal_nonce = event.params.proposal.nonce - entity.proposal_loanContract = event.params.proposal.loanContract + eventEntity.durationOrDate = event.params.proposal.durationOrDate + eventEntity.expiration = event.params.proposal.expiration + eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor + eventEntity.proposer = event.params.proposal.proposer + eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash + eventEntity.isOffer = event.params.proposal.isOffer + eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId + eventEntity.nonceSpace = event.params.proposal.nonceSpace + eventEntity.nonce = event.params.proposal.nonce + eventEntity.loanContract = event.params.proposal.loanContract - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + eventEntity.blockNumber = event.block.number + eventEntity.blockTimestamp = event.block.timestamp + eventEntity.transactionHash = event.transaction.hash - entity.save() + // Create or get the unified Proposal entity + let proposal = Proposal.load(event.params.proposalHash) + if (proposal == null) { + proposal = new Proposal(event.params.proposalHash) + + // Set proposal type + proposal.proposalType = "ElasticChainlink" + + // Set common fields + proposal.proposer = event.params.proposer + proposal.createdAt = event.block.timestamp + + // Create Asset entities + const collateralAsset = getOrCreateAsset( + event.params.proposal.collateralAddress, + event.params.proposal.collateralId, + event.params.proposal.collateralCategory + ) + const creditAsset = getOrCreateAsset( + event.params.proposal.creditAddress, + BigInt.fromI32(0), // ERC20 tokens use 0 as token ID + 0 // ERC20 tokens are category 0 + ) + + proposal.credit = creditAsset.id + proposal.fixedInterestAmount = event.params.proposal.fixedInterestAmount + proposal.accruingInterestAPR = event.params.proposal.accruingInterestAPR + proposal.availableCreditLimit = event.params.proposal.availableCreditLimit + proposal.utilizedCreditId = event.params.proposal.utilizedCreditId + proposal.durationOrDate = event.params.proposal.durationOrDate + proposal.expiration = event.params.proposal.expiration + proposal.proposerSpecHash = event.params.proposal.proposerSpecHash + proposal.isOffer = event.params.proposal.isOffer + proposal.refinancingLoanId = event.params.proposal.refinancingLoanId + proposal.nonceSpace = event.params.proposal.nonceSpace + proposal.nonce = event.params.proposal.nonce + proposal.loanContract = event.params.proposal.loanContract + proposal.status = "Active" + proposal.blockNumber = event.block.number + proposal.transactionHash = event.transaction.hash + + // Set ElasticChainlink-specific fields + proposal.collateral = collateralAsset.id + proposal.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint + proposal.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint + proposal.allowedAcceptor = event.params.proposal.allowedAcceptor + proposal.minCreditAmount = event.params.proposal.minCreditAmount + proposal.feedIntermediaryDenominations = changetype(event.params.proposal.feedIntermediaryDenominations) + proposal.feedInvertFlags = event.params.proposal.feedInvertFlags + proposal.loanToValue = event.params.proposal.loanToValue + + // Link to raw event entity + proposal.rawEventElasticChainlink = eventEntity.id + + proposal.save() + } + + // Link the event entity to the unified proposal + eventEntity.proposal = proposal.id + eventEntity.save() } diff --git a/packages/subgraph/src/simple-loan-elastic-proposal.ts b/packages/subgraph/src/simple-loan-elastic-proposal.ts index a1ca09a2..f71b6fa8 100644 --- a/packages/subgraph/src/simple-loan-elastic-proposal.ts +++ b/packages/subgraph/src/simple-loan-elastic-proposal.ts @@ -1,44 +1,104 @@ import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" -import { SimpleLoanElasticProposalProposalMade } from "../generated/schema" +import { SimpleLoanElasticProposalProposalMade, Proposal } from "../generated/schema" +import { getOrCreateAsset } from "./utils" +import { BigInt } from "@graphprotocol/graph-ts" export function handleProposalMade(event: ProposalMadeEvent): void { - const entity = new SimpleLoanElasticProposalProposalMade( + // Create the specific event entity + const eventEntity = new SimpleLoanElasticProposalProposalMade( event.transaction.hash.concatI32(event.logIndex.toI32()), ) - entity.proposalHash = event.params.proposalHash - entity.proposer = event.params.proposer - entity.proposal_collateralCategory = event.params.proposal.collateralCategory - entity.proposal_collateralAddress = event.params.proposal.collateralAddress - entity.proposal_collateralId = event.params.proposal.collateralId - entity.proposal_checkCollateralStateFingerprint = + eventEntity.proposalHash = event.params.proposalHash + eventEntity.proposer = event.params.proposer + eventEntity.collateralCategory = event.params.proposal.collateralCategory + eventEntity.collateralAddress = event.params.proposal.collateralAddress + eventEntity.collateralId = event.params.proposal.collateralId + eventEntity.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint - entity.proposal_collateralStateFingerprint = + eventEntity.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint - entity.proposal_creditAddress = event.params.proposal.creditAddress - entity.proposal_creditPerCollateralUnit = + eventEntity.creditAddress = event.params.proposal.creditAddress + eventEntity.creditPerCollateralUnit = event.params.proposal.creditPerCollateralUnit - entity.proposal_minCreditAmount = event.params.proposal.minCreditAmount - entity.proposal_availableCreditLimit = + eventEntity.minCreditAmount = event.params.proposal.minCreditAmount + eventEntity.availableCreditLimit = event.params.proposal.availableCreditLimit - entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId - entity.proposal_fixedInterestAmount = + eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId + eventEntity.fixedInterestAmount = event.params.proposal.fixedInterestAmount - entity.proposal_accruingInterestAPR = + eventEntity.accruingInterestAPR = event.params.proposal.accruingInterestAPR - entity.proposal_durationOrDate = event.params.proposal.durationOrDate - entity.proposal_expiration = event.params.proposal.expiration - entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor - entity.proposal_proposer = event.params.proposal.proposer - entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash - entity.proposal_isOffer = event.params.proposal.isOffer - entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId - entity.proposal_nonceSpace = event.params.proposal.nonceSpace - entity.proposal_nonce = event.params.proposal.nonce - entity.proposal_loanContract = event.params.proposal.loanContract + eventEntity.durationOrDate = event.params.proposal.durationOrDate + eventEntity.expiration = event.params.proposal.expiration + eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor + eventEntity.proposer = event.params.proposal.proposer + eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash + eventEntity.isOffer = event.params.proposal.isOffer + eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId + eventEntity.nonceSpace = event.params.proposal.nonceSpace + eventEntity.nonce = event.params.proposal.nonce + eventEntity.loanContract = event.params.proposal.loanContract - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + eventEntity.blockNumber = event.block.number + eventEntity.blockTimestamp = event.block.timestamp + eventEntity.transactionHash = event.transaction.hash - entity.save() + // Create or get the unified Proposal entity + let proposal = Proposal.load(event.params.proposalHash) + if (proposal == null) { + proposal = new Proposal(event.params.proposalHash) + + // Set proposal type + proposal.proposalType = "Elastic" + + // Set common fields + proposal.proposer = event.params.proposer + proposal.createdAt = event.block.timestamp + + // Create Asset entities + const collateralAsset = getOrCreateAsset( + event.params.proposal.collateralAddress, + event.params.proposal.collateralId, + event.params.proposal.collateralCategory + ) + const creditAsset = getOrCreateAsset( + event.params.proposal.creditAddress, + BigInt.fromI32(0), // ERC20 tokens use 0 as token ID + 0 // ERC20 tokens are category 0 + ) + + proposal.credit = creditAsset.id + proposal.fixedInterestAmount = event.params.proposal.fixedInterestAmount + proposal.accruingInterestAPR = event.params.proposal.accruingInterestAPR + proposal.availableCreditLimit = event.params.proposal.availableCreditLimit + proposal.utilizedCreditId = event.params.proposal.utilizedCreditId + proposal.durationOrDate = event.params.proposal.durationOrDate + proposal.expiration = event.params.proposal.expiration + proposal.proposerSpecHash = event.params.proposal.proposerSpecHash + proposal.isOffer = event.params.proposal.isOffer + proposal.refinancingLoanId = event.params.proposal.refinancingLoanId + proposal.nonceSpace = event.params.proposal.nonceSpace + proposal.nonce = event.params.proposal.nonce + proposal.loanContract = event.params.proposal.loanContract + proposal.status = "Active" + proposal.blockNumber = event.block.number + proposal.transactionHash = event.transaction.hash + + // Set Elastic-specific fields + proposal.collateral = collateralAsset.id + proposal.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint + proposal.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint + proposal.allowedAcceptor = event.params.proposal.allowedAcceptor + proposal.creditPerCollateralUnit = event.params.proposal.creditPerCollateralUnit + proposal.minCreditAmount = event.params.proposal.minCreditAmount + + // Link to raw event entity + proposal.rawEventElastic = eventEntity.id + + proposal.save() + } + + // Link the event entity to the unified proposal + eventEntity.proposal = proposal.id + eventEntity.save() } diff --git a/packages/subgraph/src/simple-loan-list-proposal.ts b/packages/subgraph/src/simple-loan-list-proposal.ts index 871b3e84..2933a710 100644 --- a/packages/subgraph/src/simple-loan-list-proposal.ts +++ b/packages/subgraph/src/simple-loan-list-proposal.ts @@ -1,44 +1,105 @@ import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" -import { SimpleLoanListProposalProposalMade } from "../generated/schema" +import { SimpleLoanListProposalProposalMade, Proposal } from "../generated/schema" +import { getOrCreateAsset } from "./utils" +import { BigInt } from "@graphprotocol/graph-ts" export function handleProposalMade(event: ProposalMadeEvent): void { - const entity = new SimpleLoanListProposalProposalMade( + // Create the specific event entity + const eventEntity = new SimpleLoanListProposalProposalMade( event.transaction.hash.concatI32(event.logIndex.toI32()), ) - entity.proposalHash = event.params.proposalHash - entity.proposer = event.params.proposer - entity.proposal_collateralCategory = event.params.proposal.collateralCategory - entity.proposal_collateralAddress = event.params.proposal.collateralAddress - entity.proposal_collateralIdsWhitelistMerkleRoot = + eventEntity.proposalHash = event.params.proposalHash + eventEntity.proposer = event.params.proposer + eventEntity.collateralCategory = event.params.proposal.collateralCategory + eventEntity.collateralAddress = event.params.proposal.collateralAddress + eventEntity.collateralIdsWhitelistMerkleRoot = event.params.proposal.collateralIdsWhitelistMerkleRoot - entity.proposal_collateralAmount = event.params.proposal.collateralAmount - entity.proposal_checkCollateralStateFingerprint = + eventEntity.collateralAmount = event.params.proposal.collateralAmount + eventEntity.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint - entity.proposal_collateralStateFingerprint = + eventEntity.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint - entity.proposal_creditAddress = event.params.proposal.creditAddress - entity.proposal_creditAmount = event.params.proposal.creditAmount - entity.proposal_availableCreditLimit = + eventEntity.creditAddress = event.params.proposal.creditAddress + eventEntity.creditAmount = event.params.proposal.creditAmount + eventEntity.availableCreditLimit = event.params.proposal.availableCreditLimit - entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId - entity.proposal_fixedInterestAmount = + eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId + eventEntity.fixedInterestAmount = event.params.proposal.fixedInterestAmount - entity.proposal_accruingInterestAPR = + eventEntity.accruingInterestAPR = event.params.proposal.accruingInterestAPR - entity.proposal_durationOrDate = event.params.proposal.durationOrDate - entity.proposal_expiration = event.params.proposal.expiration - entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor - entity.proposal_proposer = event.params.proposal.proposer - entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash - entity.proposal_isOffer = event.params.proposal.isOffer - entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId - entity.proposal_nonceSpace = event.params.proposal.nonceSpace - entity.proposal_nonce = event.params.proposal.nonce - entity.proposal_loanContract = event.params.proposal.loanContract + eventEntity.durationOrDate = event.params.proposal.durationOrDate + eventEntity.expiration = event.params.proposal.expiration + eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor + eventEntity.proposerAddress = event.params.proposal.proposer + eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash + eventEntity.isOffer = event.params.proposal.isOffer + eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId + eventEntity.nonceSpace = event.params.proposal.nonceSpace + eventEntity.nonce = event.params.proposal.nonce + eventEntity.loanContract = event.params.proposal.loanContract - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + eventEntity.blockNumber = event.block.number + eventEntity.blockTimestamp = event.block.timestamp + eventEntity.transactionHash = event.transaction.hash - entity.save() + // Create or get the unified Proposal entity + let proposal = Proposal.load(event.params.proposalHash) + if (proposal == null) { + proposal = new Proposal(event.params.proposalHash) + + // Set proposal type + proposal.proposalType = "List" + + // Set common fields + proposal.proposer = event.params.proposer + proposal.createdAt = event.block.timestamp + + // Create Asset entities + const collateralAsset = getOrCreateAsset( + event.params.proposal.collateralAddress, + BigInt.fromI32(0), // List proposals don't have specific token ID, using 0 + event.params.proposal.collateralCategory + ) + const creditAsset = getOrCreateAsset( + event.params.proposal.creditAddress, + BigInt.fromI32(0), // ERC20 tokens use 0 as token ID + 0 // ERC20 tokens are category 0 + ) + + proposal.credit = creditAsset.id + proposal.fixedInterestAmount = event.params.proposal.fixedInterestAmount + proposal.accruingInterestAPR = event.params.proposal.accruingInterestAPR + proposal.availableCreditLimit = event.params.proposal.availableCreditLimit + proposal.utilizedCreditId = event.params.proposal.utilizedCreditId + proposal.durationOrDate = event.params.proposal.durationOrDate + proposal.expiration = event.params.proposal.expiration + proposal.proposerSpecHash = event.params.proposal.proposerSpecHash + proposal.isOffer = event.params.proposal.isOffer + proposal.refinancingLoanId = event.params.proposal.refinancingLoanId + proposal.nonceSpace = event.params.proposal.nonceSpace + proposal.nonce = event.params.proposal.nonce + proposal.loanContract = event.params.proposal.loanContract + proposal.status = "Active" + proposal.blockNumber = event.block.number + proposal.transactionHash = event.transaction.hash + + // Set List-specific fields + proposal.collateral = collateralAsset.id + proposal.collateralAmount = event.params.proposal.collateralAmount + proposal.creditAmount = event.params.proposal.creditAmount + proposal.allowedAcceptor = event.params.proposal.allowedAcceptor + proposal.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint + proposal.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint + proposal.collateralIdsWhitelistMerkleRoot = event.params.proposal.collateralIdsWhitelistMerkleRoot + + // Link to raw event entity + proposal.rawEventList = eventEntity.id + + proposal.save() + } + + // Link the event entity to the unified proposal + eventEntity.proposal = proposal.id + eventEntity.save() } diff --git a/packages/subgraph/src/simple-loan-simple-proposal.ts b/packages/subgraph/src/simple-loan-simple-proposal.ts index a2210e37..b3061c28 100644 --- a/packages/subgraph/src/simple-loan-simple-proposal.ts +++ b/packages/subgraph/src/simple-loan-simple-proposal.ts @@ -1,43 +1,103 @@ import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" -import { ProposalMade } from "../generated/schema" +import { SimpleLoanSimpleProposalMade, Proposal } from "../generated/schema" +import { getOrCreateAsset } from "./utils" +import { BigInt } from "@graphprotocol/graph-ts" export function handleProposalMade(event: ProposalMadeEvent): void { - const entity = new ProposalMade( + // Create the specific event entity + const eventEntity = new SimpleLoanSimpleProposalMade( event.transaction.hash.concatI32(event.logIndex.toI32()), ) - entity.proposalHash = event.params.proposalHash - entity.proposer = event.params.proposer - entity.proposal_collateralCategory = event.params.proposal.collateralCategory - entity.proposal_collateralAddress = event.params.proposal.collateralAddress - entity.proposal_collateralId = event.params.proposal.collateralId - entity.proposal_collateralAmount = event.params.proposal.collateralAmount - entity.proposal_checkCollateralStateFingerprint = + eventEntity.proposalHash = event.params.proposalHash + eventEntity.proposer = event.params.proposer + eventEntity.collateralCategory = event.params.proposal.collateralCategory + eventEntity.collateralAddress = event.params.proposal.collateralAddress + eventEntity.collateralId = event.params.proposal.collateralId + eventEntity.collateralAmount = event.params.proposal.collateralAmount + eventEntity.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint - entity.proposal_collateralStateFingerprint = + eventEntity.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint - entity.proposal_creditAddress = event.params.proposal.creditAddress - entity.proposal_creditAmount = event.params.proposal.creditAmount - entity.proposal_availableCreditLimit = + eventEntity.creditAddress = event.params.proposal.creditAddress + eventEntity.creditAmount = event.params.proposal.creditAmount + eventEntity.availableCreditLimit = event.params.proposal.availableCreditLimit - entity.proposal_utilizedCreditId = event.params.proposal.utilizedCreditId - entity.proposal_fixedInterestAmount = + eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId + eventEntity.fixedInterestAmount = event.params.proposal.fixedInterestAmount - entity.proposal_accruingInterestAPR = + eventEntity.accruingInterestAPR = event.params.proposal.accruingInterestAPR - entity.proposal_durationOrDate = event.params.proposal.durationOrDate - entity.proposal_expiration = event.params.proposal.expiration - entity.proposal_allowedAcceptor = event.params.proposal.allowedAcceptor - entity.proposal_proposer = event.params.proposal.proposer - entity.proposal_proposerSpecHash = event.params.proposal.proposerSpecHash - entity.proposal_isOffer = event.params.proposal.isOffer - entity.proposal_refinancingLoanId = event.params.proposal.refinancingLoanId - entity.proposal_nonceSpace = event.params.proposal.nonceSpace - entity.proposal_nonce = event.params.proposal.nonce - entity.proposal_loanContract = event.params.proposal.loanContract + eventEntity.durationOrDate = event.params.proposal.durationOrDate + eventEntity.expiration = event.params.proposal.expiration + eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor + eventEntity.proposerAddress = event.params.proposal.proposer + eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash + eventEntity.isOffer = event.params.proposal.isOffer + eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId + eventEntity.nonceSpace = event.params.proposal.nonceSpace + eventEntity.nonce = event.params.proposal.nonce + eventEntity.loanContract = event.params.proposal.loanContract - entity.blockNumber = event.block.number - entity.blockTimestamp = event.block.timestamp - entity.transactionHash = event.transaction.hash + eventEntity.blockNumber = event.block.number + eventEntity.blockTimestamp = event.block.timestamp + eventEntity.transactionHash = event.transaction.hash - entity.save() + // Create or get the unified Proposal entity + let proposal = Proposal.load(event.params.proposalHash) + if (proposal == null) { + proposal = new Proposal(event.params.proposalHash) + + // Set proposal type + proposal.proposalType = "Simple" + + // Set common fields + proposal.proposer = event.params.proposer + proposal.createdAt = event.block.timestamp + + // Create Asset entities + const collateralAsset = getOrCreateAsset( + event.params.proposal.collateralAddress, + event.params.proposal.collateralId, + event.params.proposal.collateralCategory + ) + const creditAsset = getOrCreateAsset( + event.params.proposal.creditAddress, + BigInt.fromI32(0), // ERC20 tokens use 0 as token ID + 0 // ERC20 tokens are category 0 + ) + + proposal.credit = creditAsset.id + proposal.fixedInterestAmount = event.params.proposal.fixedInterestAmount + proposal.accruingInterestAPR = event.params.proposal.accruingInterestAPR + proposal.availableCreditLimit = event.params.proposal.availableCreditLimit + proposal.utilizedCreditId = event.params.proposal.utilizedCreditId + proposal.durationOrDate = event.params.proposal.durationOrDate + proposal.expiration = event.params.proposal.expiration + proposal.proposerSpecHash = event.params.proposal.proposerSpecHash + proposal.isOffer = event.params.proposal.isOffer + proposal.refinancingLoanId = event.params.proposal.refinancingLoanId + proposal.nonceSpace = event.params.proposal.nonceSpace + proposal.nonce = event.params.proposal.nonce + proposal.loanContract = event.params.proposal.loanContract + proposal.status = "Active" + proposal.blockNumber = event.block.number + proposal.transactionHash = event.transaction.hash + + // Set Simple-specific fields + proposal.collateral = collateralAsset.id + proposal.collateralAmount = event.params.proposal.collateralAmount + proposal.creditAmount = event.params.proposal.creditAmount + proposal.allowedAcceptor = event.params.proposal.allowedAcceptor + proposal.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint + proposal.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint + + // Link to raw event entity + proposal.rawEventSimple = eventEntity.id + + proposal.save() + } + + // Link the event entity to the unified proposal + eventEntity.proposal = proposal.id + eventEntity.save() } diff --git a/packages/subgraph/src/simple-loan-uniswap-v-3-lp-individual-proposal.ts b/packages/subgraph/src/simple-loan-uniswap-v-3-lp-individual-proposal.ts new file mode 100644 index 00000000..ad51e030 --- /dev/null +++ b/packages/subgraph/src/simple-loan-uniswap-v-3-lp-individual-proposal.ts @@ -0,0 +1,108 @@ +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanUniswapV3LPIndividualProposal/SimpleLoanUniswapV3LPIndividualProposal" +import { SimpleLoanUniswapV3LPIndividualProposalProposalMade, Proposal } from "../generated/schema" +import { getOrCreateAsset } from "./utils" +import { Bytes, BigInt } from "@graphprotocol/graph-ts" + +export function handleProposalMade(event: ProposalMadeEvent): void { + // Create the specific event entity + const eventEntity = new SimpleLoanUniswapV3LPIndividualProposalProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + eventEntity.proposalHash = event.params.proposalHash + eventEntity.proposer = event.params.proposer + eventEntity.collateralId = event.params.proposal.collateralId + eventEntity.token0Denominator = event.params.proposal.token0Denominator + eventEntity.creditAddress = event.params.proposal.creditAddress + eventEntity.feedIntermediaryDenominations = changetype( + event.params.proposal.feedIntermediaryDenominations, + ) + eventEntity.feedInvertFlags = event.params.proposal.feedInvertFlags + eventEntity.loanToValue = event.params.proposal.loanToValue + eventEntity.minCreditAmount = event.params.proposal.minCreditAmount + eventEntity.availableCreditLimit = + event.params.proposal.availableCreditLimit + eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId + eventEntity.fixedInterestAmount = + event.params.proposal.fixedInterestAmount + eventEntity.accruingInterestAPR = + event.params.proposal.accruingInterestAPR + eventEntity.durationOrDate = event.params.proposal.durationOrDate + eventEntity.expiration = event.params.proposal.expiration + eventEntity.acceptorController = event.params.proposal.acceptorController + eventEntity.acceptorControllerData = + event.params.proposal.acceptorControllerData + eventEntity.proposer = event.params.proposal.proposer + eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash + eventEntity.isOffer = event.params.proposal.isOffer + eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId + eventEntity.nonceSpace = event.params.proposal.nonceSpace + eventEntity.nonce = event.params.proposal.nonce + eventEntity.loanContract = event.params.proposal.loanContract + + eventEntity.blockNumber = event.block.number + eventEntity.blockTimestamp = event.block.timestamp + eventEntity.transactionHash = event.transaction.hash + + // Create or get the unified Proposal entity + let proposal = Proposal.load(event.params.proposalHash) + if (proposal == null) { + proposal = new Proposal(event.params.proposalHash) + + // Set proposal type + proposal.proposalType = "UniswapV3LPIndividual" + + // Set common fields + proposal.proposer = event.params.proposer + proposal.createdAt = event.block.timestamp + + // Create Asset entities + const collateralAsset = getOrCreateAsset( + // TODO will this differ on chains? this one is uniswap v3 positions manager nft contract for sepolia + Bytes.fromHexString("0x1238536071E1c677A632429e3655c799b22cDA52"), + event.params.proposal.collateralId, + 1 // ERC721 + ) + const creditAsset = getOrCreateAsset( + event.params.proposal.creditAddress, + BigInt.fromI32(0), // ERC20 tokens use 0 as token ID + 0 // ERC20 tokens are category 0 + ) + + proposal.credit = creditAsset.id + proposal.fixedInterestAmount = event.params.proposal.fixedInterestAmount + proposal.accruingInterestAPR = event.params.proposal.accruingInterestAPR + proposal.availableCreditLimit = event.params.proposal.availableCreditLimit + proposal.utilizedCreditId = event.params.proposal.utilizedCreditId + proposal.durationOrDate = event.params.proposal.durationOrDate + proposal.expiration = event.params.proposal.expiration + proposal.proposerSpecHash = event.params.proposal.proposerSpecHash + proposal.isOffer = event.params.proposal.isOffer + proposal.refinancingLoanId = event.params.proposal.refinancingLoanId + proposal.nonceSpace = event.params.proposal.nonceSpace + proposal.nonce = event.params.proposal.nonce + proposal.loanContract = event.params.proposal.loanContract + proposal.status = "Active" + proposal.blockNumber = event.block.number + proposal.transactionHash = event.transaction.hash + + // Set UniswapV3LPIndividual-specific fields + proposal.collateral = collateralAsset.id + proposal.collateralId = event.params.proposal.collateralId + proposal.token0Denominator = event.params.proposal.token0Denominator + proposal.feedIntermediaryDenominations = changetype(event.params.proposal.feedIntermediaryDenominations) + proposal.feedInvertFlags = event.params.proposal.feedInvertFlags + proposal.loanToValue = event.params.proposal.loanToValue + proposal.minCreditAmount = event.params.proposal.minCreditAmount + proposal.acceptorController = event.params.proposal.acceptorController + proposal.acceptorControllerData = event.params.proposal.acceptorControllerData + + // Link to raw event entity + proposal.rawEventUniswapV3LPIndividual = eventEntity.id + + proposal.save() + } + + // Link the event entity to the unified proposal + eventEntity.proposal = proposal.id + eventEntity.save() +} diff --git a/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts b/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts new file mode 100644 index 00000000..e1b7a4f6 --- /dev/null +++ b/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts @@ -0,0 +1,112 @@ +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanUniswapV3LPSetProposal/SimpleLoanUniswapV3LPSetProposal" +import { SimpleLoanUniswapV3LPSetProposalProposalMade, Proposal } from "../generated/schema" +import { getOrCreateAsset } from "./utils" +import { Bytes } from "@graphprotocol/graph-ts" +import { BigInt } from "@graphprotocol/graph-ts" + +export function handleProposalMade(event: ProposalMadeEvent): void { + // Create the specific event entity + const eventEntity = new SimpleLoanUniswapV3LPSetProposalProposalMade( + event.transaction.hash.concatI32(event.logIndex.toI32()), + ) + eventEntity.proposalHash = event.params.proposalHash + eventEntity.proposer = event.params.proposer + eventEntity.tokenAAllowlist = changetype( + event.params.proposal.tokenAAllowlist, + ) + eventEntity.tokenBAllowlist = changetype( + event.params.proposal.tokenBAllowlist, + ) + eventEntity.creditAddress = event.params.proposal.creditAddress + eventEntity.feedIntermediaryDenominations = changetype( + event.params.proposal.feedIntermediaryDenominations, + ) + eventEntity.feedInvertFlags = event.params.proposal.feedInvertFlags + eventEntity.loanToValue = event.params.proposal.loanToValue + eventEntity.minCreditAmount = event.params.proposal.minCreditAmount + eventEntity.availableCreditLimit = + event.params.proposal.availableCreditLimit + eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId + eventEntity.fixedInterestAmount = + event.params.proposal.fixedInterestAmount + eventEntity.accruingInterestAPR = + event.params.proposal.accruingInterestAPR + eventEntity.durationOrDate = event.params.proposal.durationOrDate + eventEntity.expiration = event.params.proposal.expiration + eventEntity.acceptorController = event.params.proposal.acceptorController + eventEntity.acceptorControllerData = + event.params.proposal.acceptorControllerData + eventEntity.proposer = event.params.proposal.proposer + eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash + eventEntity.isOffer = event.params.proposal.isOffer + eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId + eventEntity.nonceSpace = event.params.proposal.nonceSpace + eventEntity.nonce = event.params.proposal.nonce + eventEntity.loanContract = event.params.proposal.loanContract + + eventEntity.blockNumber = event.block.number + eventEntity.blockTimestamp = event.block.timestamp + eventEntity.transactionHash = event.transaction.hash + + // Create or get the unified Proposal entity + let proposal = Proposal.load(event.params.proposalHash) + if (proposal == null) { + proposal = new Proposal(event.params.proposalHash) + + // Set proposal type + proposal.proposalType = "UniswapV3LPSet" + + // Set common fields + proposal.proposer = event.params.proposer + proposal.createdAt = event.block.timestamp + + // Create Asset entities + const collateralAsset = getOrCreateAsset( + event.params.proposal.collateralAddress, + BigInt.fromI32(0), // UniswapV3 LP Set doesn't have specific token ID + event.params.proposal.collateralCategory + ) + const creditAsset = getOrCreateAsset( + event.params.proposal.creditAddress, + BigInt.fromI32(0), // ERC20 tokens use 0 as token ID + 0 // ERC20 tokens are category 0 + ) + + proposal.credit = creditAsset.id + proposal.fixedInterestAmount = event.params.proposal.fixedInterestAmount + proposal.accruingInterestAPR = event.params.proposal.accruingInterestAPR + proposal.availableCreditLimit = event.params.proposal.availableCreditLimit + proposal.utilizedCreditId = event.params.proposal.utilizedCreditId + proposal.durationOrDate = event.params.proposal.durationOrDate + proposal.expiration = event.params.proposal.expiration + proposal.proposerSpecHash = event.params.proposal.proposerSpecHash + proposal.isOffer = event.params.proposal.isOffer + proposal.refinancingLoanId = event.params.proposal.refinancingLoanId + proposal.nonceSpace = event.params.proposal.nonceSpace + proposal.nonce = event.params.proposal.nonce + proposal.loanContract = event.params.proposal.loanContract + proposal.status = "Active" + proposal.blockNumber = event.block.number + proposal.transactionHash = event.transaction.hash + + // Set UniswapV3LPSet-specific fields + proposal.collateral = collateralAsset.id + proposal.tokenAAllowlist = changetype(event.params.proposal.tokenAAllowlist) + proposal.tokenBAllowlist = changetype(event.params.proposal.tokenBAllowlist) + proposal.feedIntermediaryDenominations = changetype(event.params.proposal.feedIntermediaryDenominations) + proposal.feedInvertFlags = event.params.proposal.feedInvertFlags + proposal.loanToValue = event.params.proposal.loanToValue + proposal.minCreditAmount = event.params.proposal.minCreditAmount + proposal.acceptorController = event.params.proposal.acceptorController + proposal.acceptorControllerData = event.params.proposal.acceptorControllerData + + // Link to raw event entity + proposal.rawEventUniswapV3LPSet = eventEntity.id + + proposal.save() + } + + // Link the event entity to the unified proposal + eventEntity.proposal = proposal.id + eventEntity.save() +} diff --git a/packages/subgraph/src/simple-loan.ts b/packages/subgraph/src/simple-loan.ts index 1f0930ce..08d7eee3 100644 --- a/packages/subgraph/src/simple-loan.ts +++ b/packages/subgraph/src/simple-loan.ts @@ -12,10 +12,11 @@ import { LOANExtended, Loan, } from "../generated/schema" -import { getOrCreateAccount, getOrCreateAsset } from "./loan-mapping" +import { getOrCreateAccount } from "./helpers" +import { getOrCreateAsset } from "./utils" export function getLoanId(loanContractAddress: Address, loanId: BigInt): Bytes { - return loanContractAddress.concat(Bytes.fromBigInt(loanId)) + return loanContractAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) } export function handleLOANCreated(event: LOANCreatedEvent): void { @@ -33,9 +34,9 @@ export function handleLOANCreated(event: LOANCreatedEvent): void { loan.createdAt = event.block.timestamp - loan.collateral = getOrCreateAsset(event.params.terms.collateral).id + loan.collateral = getOrCreateAsset(event.params.terms.collateral.assetAddress, event.params.terms.collateral.id, event.params.terms.collateral.category).id loan.collateralAmount = event.params.terms.collateral.amount - loan.credit = getOrCreateAsset(event.params.terms.credit).id + loan.credit = getOrCreateAsset(event.params.terms.credit.assetAddress, event.params.terms.credit.id, event.params.terms.credit.category).id loan.creditAmount = event.params.terms.credit.amount loan.status = "Active" @@ -52,7 +53,7 @@ export function handleLOANCreated(event: LOANCreatedEvent): void { loan.extra = event.params.extra - const simpleLoanContract = SimpleLoan.bind(loan.contractAddress) + const simpleLoanContract = SimpleLoan.bind(Address.fromBytes(loan.contractAddress)) loan.loanTokenAddress = simpleLoanContract.loanToken() loan.save() @@ -97,6 +98,9 @@ export function handleLOANExtended(event: LOANExtendedEvent): void { return } + const extensionDuration = event.params.extendedDefaultTimestamp.minus(loan.defaultDate); + loan.duration = loan.duration.plus(extensionDuration); + loan.defaultDate = event.params.extendedDefaultTimestamp loan.save() diff --git a/packages/subgraph/src/utils.ts b/packages/subgraph/src/utils.ts new file mode 100644 index 00000000..9b80e17d --- /dev/null +++ b/packages/subgraph/src/utils.ts @@ -0,0 +1,86 @@ +import { Asset, AssetContract, Category, Account } from "../generated/schema" +import { Bytes, BigInt, Address } from "@graphprotocol/graph-ts" + +// Helper function to create or get Asset entity +export function getOrCreateAsset(contractAddress: Bytes, tokenId: BigInt, category: i32): Asset { + const assetId = contractAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(tokenId))) + let asset = Asset.load(assetId) + + if (asset == null) { + let assetContract = AssetContract.load(contractAddress) + if (assetContract == null) { + // Create or get the category + let categoryEntity = Category.load(Bytes.fromI32(category)) + if (categoryEntity == null) { + categoryEntity = new Category(Bytes.fromI32(category)) + categoryEntity.save() + } + + assetContract = new AssetContract(contractAddress) + assetContract.category = categoryEntity.id + assetContract.save() + } + + asset = new Asset(assetId) + asset.contract = assetContract.id + asset.tokenId = tokenId + asset.save() + } + + return asset +} + +// Helper function to create or get Account entity +export function getOrCreateAccount(address: Bytes): Account { + let account = Account.load(address) + if (account == null) { + account = new Account(address) + account.save() + } + return account +} + +// Helper function to extract proposal parameters for function calls +// This removes the "proposal_" prefix from field names +export function extractProposalParams(proposalEvent: any): Map { + const params = new Map() + + // Common parameters (available in all proposal types) + if (proposalEvent.proposal_collateralCategory !== undefined) params.set("collateralCategory", proposalEvent.proposal_collateralCategory) + if (proposalEvent.proposal_collateralAddress !== undefined) params.set("collateralAddress", proposalEvent.proposal_collateralAddress) + if (proposalEvent.proposal_collateralId !== undefined) params.set("collateralId", proposalEvent.proposal_collateralId) + if (proposalEvent.proposal_collateralAmount !== undefined) params.set("collateralAmount", proposalEvent.proposal_collateralAmount) + if (proposalEvent.proposal_checkCollateralStateFingerprint !== undefined) params.set("checkCollateralStateFingerprint", proposalEvent.proposal_checkCollateralStateFingerprint) + if (proposalEvent.proposal_collateralStateFingerprint !== undefined) params.set("collateralStateFingerprint", proposalEvent.proposal_collateralStateFingerprint) + if (proposalEvent.proposal_creditAddress !== undefined) params.set("creditAddress", proposalEvent.proposal_creditAddress) + if (proposalEvent.proposal_creditAmount !== undefined) params.set("creditAmount", proposalEvent.proposal_creditAmount) + if (proposalEvent.proposal_availableCreditLimit !== undefined) params.set("availableCreditLimit", proposalEvent.proposal_availableCreditLimit) + if (proposalEvent.proposal_utilizedCreditId !== undefined) params.set("utilizedCreditId", proposalEvent.proposal_utilizedCreditId) + if (proposalEvent.proposal_fixedInterestAmount !== undefined) params.set("fixedInterestAmount", proposalEvent.proposal_fixedInterestAmount) + if (proposalEvent.proposal_accruingInterestAPR !== undefined) params.set("accruingInterestAPR", proposalEvent.proposal_accruingInterestAPR) + if (proposalEvent.proposal_durationOrDate !== undefined) params.set("durationOrDate", proposalEvent.proposal_durationOrDate) + if (proposalEvent.proposal_expiration !== undefined) params.set("expiration", proposalEvent.proposal_expiration) + if (proposalEvent.proposal_allowedAcceptor !== undefined) params.set("allowedAcceptor", proposalEvent.proposal_allowedAcceptor) + if (proposalEvent.proposal_proposer !== undefined) params.set("proposer", proposalEvent.proposal_proposer) + if (proposalEvent.proposal_proposerSpecHash !== undefined) params.set("proposerSpecHash", proposalEvent.proposal_proposerSpecHash) + if (proposalEvent.proposal_isOffer !== undefined) params.set("isOffer", proposalEvent.proposal_isOffer) + if (proposalEvent.proposal_refinancingLoanId !== undefined) params.set("refinancingLoanId", proposalEvent.proposal_refinancingLoanId) + if (proposalEvent.proposal_nonceSpace !== undefined) params.set("nonceSpace", proposalEvent.proposal_nonceSpace) + if (proposalEvent.proposal_nonce !== undefined) params.set("nonce", proposalEvent.proposal_nonce) + if (proposalEvent.proposal_loanContract !== undefined) params.set("loanContract", proposalEvent.proposal_loanContract) + + // Type-specific parameters + if (proposalEvent.proposal_collateralIdsWhitelistMerkleRoot !== undefined) params.set("collateralIdsWhitelistMerkleRoot", proposalEvent.proposal_collateralIdsWhitelistMerkleRoot) + if (proposalEvent.proposal_creditPerCollateralUnit !== undefined) params.set("creditPerCollateralUnit", proposalEvent.proposal_creditPerCollateralUnit) + if (proposalEvent.proposal_minCreditAmount !== undefined) params.set("minCreditAmount", proposalEvent.proposal_minCreditAmount) + if (proposalEvent.proposal_feedIntermediaryDenominations !== undefined) params.set("feedIntermediaryDenominations", proposalEvent.proposal_feedIntermediaryDenominations) + if (proposalEvent.proposal_feedInvertFlags !== undefined) params.set("feedInvertFlags", proposalEvent.proposal_feedInvertFlags) + if (proposalEvent.proposal_loanToValue !== undefined) params.set("loanToValue", proposalEvent.proposal_loanToValue) + if (proposalEvent.proposal_token0Denominator !== undefined) params.set("token0Denominator", proposalEvent.proposal_token0Denominator) + if (proposalEvent.proposal_acceptorController !== undefined) params.set("acceptorController", proposalEvent.proposal_acceptorController) + if (proposalEvent.proposal_acceptorControllerData !== undefined) params.set("acceptorControllerData", proposalEvent.proposal_acceptorControllerData) + if (proposalEvent.proposal_tokenAAllowlist !== undefined) params.set("tokenAAllowlist", proposalEvent.proposal_tokenAAllowlist) + if (proposalEvent.proposal_tokenBAllowlist !== undefined) params.set("tokenBAllowlist", proposalEvent.proposal_tokenBAllowlist) + + return params +} \ No newline at end of file diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index 7dc95b21..e8811885 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -318,4 +318,45 @@ dataSources: #- event: OwnershipTransferred(indexed address,indexed address) # handler: handleOwnershipTransferred file: ./src/multi-token-category-registry.ts - + - kind: ethereum + name: SimpleLoanUniswapV3LPIndividualProposal + network: {{network}} + source: + address: "{{SimpleLoanUniswapV3LPIndividualProposal.address}}" + abi: SimpleLoanUniswapV3LPIndividualProposal + startBlock: {{SimpleLoanUniswapV3LPIndividualProposal.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanUniswapV3LPIndividualProposalProposalMade + abis: + - name: SimpleLoanUniswapV3LPIndividualProposal + file: ./abis/SimpleLoanUniswapV3LPIndividualProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint256,bool,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-uniswap-v-3-lp-individual-proposal.ts + - kind: ethereum + name: SimpleLoanUniswapV3LPSetProposal + network: {{network}} + source: + address: "{{SimpleLoanUniswapV3LPSetProposal.address}}" + abi: SimpleLoanUniswapV3LPSetProposal + startBlock: {{SimpleLoanUniswapV3LPSetProposal.startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanUniswapV3LPSetProposalProposalMade + abis: + - name: SimpleLoanUniswapV3LPSetProposal + file: ./abis/SimpleLoanUniswapV3LPSetProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(address[],address[],address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-uniswap-v-3-lp-set-proposal.ts diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index 17d0b47d..fdbe3146 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -21,7 +21,7 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - ProposalMade + - SimpleLoanSimpleProposalMade abis: - name: SimpleLoanSimpleProposal file: ./abis/SimpleLoanSimpleProposal.json @@ -110,11 +110,11 @@ dataSources: - LOANCreated - LOANExtended - LOANPaidBack - - PoolSupply - - PoolWithdraw - - VaultPull - - VaultPush - - VaultPushFrom + #- PoolSupply + #- PoolWithdraw + #- VaultPull + #- VaultPush + #- VaultPushFrom abis: - name: SimpleLoan file: ./abis/SimpleLoan.json @@ -131,18 +131,18 @@ dataSources: handler: handleLOANExtended - event: LOANPaidBack(indexed uint256) handler: handleLOANPaidBack - - event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed - address) - handler: handlePoolSupply - - event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed - address,indexed address) - handler: handlePoolWithdraw - - event: VaultPull((uint8,address,uint256,uint256),indexed address) - handler: handleVaultPull - - event: VaultPush((uint8,address,uint256,uint256),indexed address) - handler: handleVaultPush - - event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) - handler: handleVaultPushFrom + #- event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed + # address) + # handler: handlePoolSupply + #- event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed + # address,indexed address) + # handler: handlePoolWithdraw + #- event: VaultPull((uint8,address,uint256,uint256),indexed address) + # handler: handleVaultPull + #- event: VaultPush((uint8,address,uint256,uint256),indexed address) + # handler: handleVaultPush + #- event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) + # handler: handleVaultPushFrom file: ./src/simple-loan.ts - kind: ethereum name: LoanToken @@ -156,75 +156,77 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - Approval - - ApprovalForAll - - LOANBurned - - LOANMinted + # - Approval + # - ApprovalForAll + #- LOANBurned + #- LOANMinted - Transfer abis: - name: LoanToken file: ./abis/LoanToken.json eventHandlers: - - event: Approval(indexed address,indexed address,indexed uint256) - handler: handleApproval - - event: ApprovalForAll(indexed address,indexed address,bool) - handler: handleApprovalForAll - - event: LOANBurned(indexed uint256) - handler: handleLOANBurned - - event: LOANMinted(indexed uint256,indexed address,indexed address) - handler: handleLOANMinted + # - event: Approval(indexed address,indexed address,indexed uint256) + # handler: handleApproval + # - event: ApprovalForAll(indexed address,indexed address,bool) + # handler: handleApprovalForAll + # note: no need to track LOANBurned and LOANMinted as they happen always + # together with LOANCreated and LOANClaimed + #- event: LOANBurned(indexed uint256) + # handler: handleLOANBurned + #- event: LOANMinted(indexed uint256,indexed address,indexed address) + # handler: handleLOANMinted - event: Transfer(indexed address,indexed address,indexed uint256) handler: handleTransfer file: ./src/loan-token.ts # TODO update Config abi # TODO should we also have proxy upgrade events in the config address? - - kind: ethereum - name: Config - network: sepolia - source: - address: "0xd52a2898d61636bB3eEF0d145f05352FF543bdCC" - abi: Config - startBlock: 5953668 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - AdminChanged - - BeaconUpgraded - - Upgraded - - DefaultLOANMetadataUriUpdated - - FeeCollectorUpdated - - FeeUpdated - - Initialized - - LOANMetadataUriUpdated - - ConfigOwnershipTransferStarted - - ConfigOwnershipTransferred - abis: - - name: Config - file: ./abis/Config.json - eventHandlers: - - event: AdminChanged(address,address) - handler: handleAdminChanged - - event: BeaconUpgraded(indexed address) - handler: handleBeaconUpgraded - - event: Upgraded(indexed address) - handler: handleUpgraded - - event: DefaultLOANMetadataUriUpdated(string) - handler: handleDefaultLOANMetadataUriUpdated - - event: FeeCollectorUpdated(address,address) - handler: handleFeeCollectorUpdated - - event: FeeUpdated(uint16,uint16) - handler: handleFeeUpdated - - event: Initialized(uint8) - handler: handleInitialized - - event: LOANMetadataUriUpdated(indexed address,string) - handler: handleLOANMetadataUriUpdated - - event: OwnershipTransferStarted(indexed address,indexed address) - handler: handleOwnershipTransferStarted - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred - file: ./src/config.ts + # - kind: ethereum + # name: Config + # network: sepolia + # source: + # address: "0xd52a2898d61636bB3eEF0d145f05352FF543bdCC" + # abi: Config + # startBlock: 5953668 + # mapping: + # kind: ethereum/events + # apiVersion: 0.0.9 + # language: wasm/assemblyscript + # entities: + # #- AdminChanged + # #- BeaconUpgraded + # #- Upgraded + # - DefaultLOANMetadataUriUpdated + # - FeeCollectorUpdated + # - FeeUpdated + # #- Initialized + # - LOANMetadataUriUpdated + # #- ConfigOwnershipTransferStarted + # #- ConfigOwnershipTransferred + # abis: + # - name: Config + # file: ./abis/Config.json + # eventHandlers: + # #- event: AdminChanged(address,address) + # # handler: handleAdminChanged + # #- event: BeaconUpgraded(indexed address) + # # handler: handleBeaconUpgraded + # #- event: Upgraded(indexed address) + # # handler: handleUpgraded + # - event: DefaultLOANMetadataUriUpdated(string) + # handler: handleDefaultLOANMetadataUriUpdated + # - event: FeeCollectorUpdated(address,address) + # handler: handleFeeCollectorUpdated + # - event: FeeUpdated(uint16,uint16) + # handler: handleFeeUpdated + # #- event: Initialized(uint8) + # # handler: handleInitialized + # - event: LOANMetadataUriUpdated(indexed address,string) + # handler: handleLOANMetadataUriUpdated + # #- event: OwnershipTransferStarted(indexed address,indexed address) + # # handler: handleOwnershipTransferStarted + # #- event: OwnershipTransferred(indexed address,indexed address) + # # handler: handleOwnershipTransferred + # file: ./src/config.ts - kind: ethereum name: Hub network: sepolia @@ -237,17 +239,17 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - OwnershipTransferStarted - - OwnershipTransferred + #- OwnershipTransferStarted + #- OwnershipTransferred - TagSet abis: - name: Hub file: ./abis/Hub.json eventHandlers: - - event: OwnershipTransferStarted(indexed address,indexed address) - handler: handleOwnershipTransferStarted - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: OwnershipTransferStarted(indexed address,indexed address) + # handler: handleOwnershipTransferStarted + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred - event: TagSet(indexed address,indexed bytes32,bool) handler: handleTagSet file: ./src/hub.ts @@ -263,26 +265,27 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - AccessControllerSet - - FeedConfirmed - - FeedProposed - - OwnershipTransferRequested - - ChainlinkFeedRegistryOwnershipTransferred + #- AccessControllerSet + - ChainlinkFeed + #- FeedConfirmed + #- FeedProposed + #- OwnershipTransferRequested + #- ChainlinkFeedRegistryOwnershipTransferred abis: - name: ChainlinkFeedRegistry file: ./abis/ChainlinkFeedRegistry.json eventHandlers: - - event: AccessControllerSet(indexed address,indexed address) - handler: handleAccessControllerSet + #- event: AccessControllerSet(indexed address,indexed address) + # handler: handleAccessControllerSet - event: FeedConfirmed(indexed address,indexed address,indexed address,address,uint16,address) handler: handleFeedConfirmed - - event: FeedProposed(indexed address,indexed address,indexed address,address,address) - handler: handleFeedProposed - - event: OwnershipTransferRequested(indexed address,indexed address) - handler: handleOwnershipTransferRequested - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: FeedProposed(indexed address,indexed address,indexed address,address,address) + # handler: handleFeedProposed + #- event: OwnershipTransferRequested(indexed address,indexed address) + # handler: handleOwnershipTransferRequested + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred file: ./src/chainlink-feed-registry.ts - kind: ethereum name: MultiTokenCategoryRegistry @@ -296,10 +299,12 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - CategoryRegistered - - CategoryUnregistered - - MultiTokenCategoryRegistryOwnershipTransferStarted - - MultiTokenCategoryRegistryOwnershipTransferred + - AssetInCategory + - Category + #- CategoryRegistered + #- CategoryUnregistered + #- MultiTokenCategoryRegistryOwnershipTransferStarted + #- MultiTokenCategoryRegistryOwnershipTransferred abis: - name: MultiTokenCategoryRegistry file: ./abis/MultiTokenCategoryRegistry.json @@ -308,9 +313,52 @@ dataSources: handler: handleCategoryRegistered - event: CategoryUnregistered(indexed address) handler: handleCategoryUnregistered - - event: OwnershipTransferStarted(indexed address,indexed address) - handler: handleOwnershipTransferStarted - - event: OwnershipTransferred(indexed address,indexed address) - handler: handleOwnershipTransferred + #- event: OwnershipTransferStarted(indexed address,indexed address) + # handler: handleOwnershipTransferStarted + #- event: OwnershipTransferred(indexed address,indexed address) + # handler: handleOwnershipTransferred file: ./src/multi-token-category-registry.ts - + # TODO add uniswap lp proposals contract address categories to mainnet + - kind: ethereum + name: SimpleLoanUniswapV3LPIndividualProposal + network: sepolia + source: + address: "0xF966696BE0623447679AC830FC5bB7bDB15FEAB4" + abi: SimpleLoanUniswapV3LPIndividualProposal + startBlock: 8518575 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanUniswapV3LPIndividualProposalProposalMade + abis: + - name: SimpleLoanUniswapV3LPIndividualProposal + file: ./abis/SimpleLoanUniswapV3LPIndividualProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(uint256,bool,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-uniswap-v-3-lp-individual-proposal.ts + # TODO add uniswap lp proposals contract address categories to mainnet + - kind: ethereum + name: SimpleLoanUniswapV3LPSetProposal + network: sepolia + source: + address: "0x7b48798CE8e95f1412078cF2e1a176CA12839AfA" + abi: SimpleLoanUniswapV3LPSetProposal + startBlock: 8518575 + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - SimpleLoanUniswapV3LPSetProposalProposalMade + abis: + - name: SimpleLoanUniswapV3LPSetProposal + file: ./abis/SimpleLoanUniswapV3LPSetProposal.json + eventHandlers: + - event: ProposalMade(indexed bytes32,indexed + address,(address[],address[],address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) + handler: handleProposalMade + file: ./src/simple-loan-uniswap-v-3-lp-set-proposal.ts diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts new file mode 100644 index 00000000..d1ad3e5f --- /dev/null +++ b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts @@ -0,0 +1,28 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanUniswapV3LPIndividualProposal/SimpleLoanUniswapV3LPIndividualProposal" + +export function createProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ProposalMade { + let proposalMadeEvent = changetype(newMockEvent()) + + proposalMadeEvent.parameters = new Array() + + proposalMadeEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return proposalMadeEvent +} diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts new file mode 100644 index 00000000..f64cce11 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/schema" +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanUniswapV3LPIndividualProposal/SimpleLoanUniswapV3LPIndividualProposal" +import { handleProposalMade } from "../src/simple-loan-uniswap-v-3-lp-individual-proposal" +import { createProposalMadeEvent } from "./simple-loan-uniswap-v-3-lp-individual-proposal-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let proposalHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newProposalMadeEvent = createProposalMadeEvent( + proposalHash, + proposer, + proposal + ) + handleProposalMade(newProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ProposalMade created and stored", () => { + assert.entityCount("ProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposalHash", + "1234567890" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts new file mode 100644 index 00000000..e5036e4b --- /dev/null +++ b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts @@ -0,0 +1,28 @@ +import { newMockEvent } from "matchstick-as" +import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanUniswapV3LPSetProposal/SimpleLoanUniswapV3LPSetProposal" + +export function createProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + proposal: ethereum.Tuple +): ProposalMade { + let proposalMadeEvent = changetype(newMockEvent()) + + proposalMadeEvent.parameters = new Array() + + proposalMadeEvent.parameters.push( + new ethereum.EventParam( + "proposalHash", + ethereum.Value.fromFixedBytes(proposalHash) + ) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + proposalMadeEvent.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) + ) + + return proposalMadeEvent +} diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts new file mode 100644 index 00000000..c5d587a5 --- /dev/null +++ b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts @@ -0,0 +1,66 @@ +import { + assert, + describe, + test, + clearStore, + beforeAll, + afterAll +} from "matchstick-as/assembly/index" +import { Bytes, Address } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/schema" +import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanUniswapV3LPSetProposal/SimpleLoanUniswapV3LPSetProposal" +import { handleProposalMade } from "../src/simple-loan-uniswap-v-3-lp-set-proposal" +import { createProposalMadeEvent } from "./simple-loan-uniswap-v-3-lp-set-proposal-utils" + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure + +describe("Describe entity assertions", () => { + beforeAll(() => { + let proposalHash = Bytes.fromI32(1234567890) + let proposer = Address.fromString( + "0x0000000000000000000000000000000000000001" + ) + let proposal = "ethereum.Tuple Not implemented" + let newProposalMadeEvent = createProposalMadeEvent( + proposalHash, + proposer, + proposal + ) + handleProposalMade(newProposalMadeEvent) + }) + + afterAll(() => { + clearStore() + }) + + // For more test scenarios, see: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + + test("ProposalMade created and stored", () => { + assert.entityCount("ProposalMade", 1) + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposalHash", + "1234567890" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposer", + "0x0000000000000000000000000000000000000001" + ) + assert.fieldEquals( + "ProposalMade", + "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "proposal", + "ethereum.Tuple Not implemented" + ) + + // More assert options: + // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + }) +}) From 77e2d399331760ab3464b7bea4a224f08bf22b05 Mon Sep 17 00:00:00 2001 From: microHoffman Date: Tue, 10 Jun 2025 23:48:30 +0200 Subject: [PATCH 07/13] feat: first fully working version --- packages/subgraph/package.json | 2 +- ...simple-loan-uniswap-v-3-lp-set-proposal.ts | 7 -- packages/subgraph/subgraph.template.yaml | 94 +++++++++---------- packages/subgraph/subgraph.yaml | 4 +- 4 files changed, 49 insertions(+), 58 deletions(-) diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index 160601fc..04923a1b 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -19,7 +19,7 @@ "prepare:sepolia": "mustache config/sepolia.json subgraph.template.yaml > subgraph.yaml", "codegen": "nx exec -- graph codegen", "build": "nx exec -- graph build", - "deploy": "nx exec -- graph deploy --node https://api.studio.thegraph.com/deploy/ pwn-test-proposals", + "deploy": "nx exec -- graph deploy pwn-test-proposals subgraph.yaml", "create-local": "nx exec -- graph create --node http://localhost:8020/ pwn-test-proposals", "remove-local": "nx exec -- graph remove --node http://localhost:8020/ pwn-test-proposals", "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals" diff --git a/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts b/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts index e1b7a4f6..c19525b4 100644 --- a/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts +++ b/packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts @@ -60,12 +60,6 @@ export function handleProposalMade(event: ProposalMadeEvent): void { proposal.proposer = event.params.proposer proposal.createdAt = event.block.timestamp - // Create Asset entities - const collateralAsset = getOrCreateAsset( - event.params.proposal.collateralAddress, - BigInt.fromI32(0), // UniswapV3 LP Set doesn't have specific token ID - event.params.proposal.collateralCategory - ) const creditAsset = getOrCreateAsset( event.params.proposal.creditAddress, BigInt.fromI32(0), // ERC20 tokens use 0 as token ID @@ -90,7 +84,6 @@ export function handleProposalMade(event: ProposalMadeEvent): void { proposal.transactionHash = event.transaction.hash // Set UniswapV3LPSet-specific fields - proposal.collateral = collateralAsset.id proposal.tokenAAllowlist = changetype(event.params.proposal.tokenAAllowlist) proposal.tokenBAllowlist = changetype(event.params.proposal.tokenBAllowlist) proposal.feedIntermediaryDenominations = changetype(event.params.proposal.feedIntermediaryDenominations) diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index e8811885..26d569ce 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -180,53 +180,53 @@ dataSources: file: ./src/loan-token.ts # TODO update Config abi # TODO should we also have proxy upgrade events in the config address? - - kind: ethereum - name: Config - network: {{network}} - source: - address: "{{Config.address}}" - abi: Config - startBlock: {{Config.startBlock}} - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - #- AdminChanged - #- BeaconUpgraded - #- Upgraded - - DefaultLOANMetadataUriUpdated - - FeeCollectorUpdated - - FeeUpdated - #- Initialized - - LOANMetadataUriUpdated - #- ConfigOwnershipTransferStarted - #- ConfigOwnershipTransferred - abis: - - name: Config - file: ./abis/Config.json - eventHandlers: - #- event: AdminChanged(address,address) - # handler: handleAdminChanged - #- event: BeaconUpgraded(indexed address) - # handler: handleBeaconUpgraded - #- event: Upgraded(indexed address) - # handler: handleUpgraded - - event: DefaultLOANMetadataUriUpdated(string) - handler: handleDefaultLOANMetadataUriUpdated - - event: FeeCollectorUpdated(address,address) - handler: handleFeeCollectorUpdated - - event: FeeUpdated(uint16,uint16) - handler: handleFeeUpdated - #- event: Initialized(uint8) - # handler: handleInitialized - - event: LOANMetadataUriUpdated(indexed address,string) - handler: handleLOANMetadataUriUpdated - #- event: OwnershipTransferStarted(indexed address,indexed address) - # handler: handleOwnershipTransferStarted - #- event: OwnershipTransferred(indexed address,indexed address) - # handler: handleOwnershipTransferred - file: ./src/config.ts + # - kind: ethereum + # name: Config + # network: {{network}} + # source: + # address: "{{Config.address}}" + # abi: Config + # startBlock: {{Config.startBlock}} + # mapping: + # kind: ethereum/events + # apiVersion: 0.0.9 + # language: wasm/assemblyscript + # entities: + # #- AdminChanged + # #- BeaconUpgraded + # #- Upgraded + # - DefaultLOANMetadataUriUpdated + # - FeeCollectorUpdated + # - FeeUpdated + # #- Initialized + # - LOANMetadataUriUpdated + # #- ConfigOwnershipTransferStarted + # #- ConfigOwnershipTransferred + # abis: + # - name: Config + # file: ./abis/Config.json + # eventHandlers: + # #- event: AdminChanged(address,address) + # # handler: handleAdminChanged + # #- event: BeaconUpgraded(indexed address) + # # handler: handleBeaconUpgraded + # #- event: Upgraded(indexed address) + # # handler: handleUpgraded + # - event: DefaultLOANMetadataUriUpdated(string) + # handler: handleDefaultLOANMetadataUriUpdated + # - event: FeeCollectorUpdated(address,address) + # handler: handleFeeCollectorUpdated + # - event: FeeUpdated(uint16,uint16) + # handler: handleFeeUpdated + # #- event: Initialized(uint8) + # # handler: handleInitialized + # - event: LOANMetadataUriUpdated(indexed address,string) + # handler: handleLOANMetadataUriUpdated + # #- event: OwnershipTransferStarted(indexed address,indexed address) + # # handler: handleOwnershipTransferStarted + # #- event: OwnershipTransferred(indexed address,indexed address) + # # handler: handleOwnershipTransferred + # file: ./src/config.ts - kind: ethereum name: Hub network: {{network}} diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index fdbe3146..bf0f9c82 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -21,7 +21,7 @@ dataSources: apiVersion: 0.0.9 language: wasm/assemblyscript entities: - - SimpleLoanSimpleProposalMade + - ProposalMade abis: - name: SimpleLoanSimpleProposal file: ./abis/SimpleLoanSimpleProposal.json @@ -318,7 +318,6 @@ dataSources: #- event: OwnershipTransferred(indexed address,indexed address) # handler: handleOwnershipTransferred file: ./src/multi-token-category-registry.ts - # TODO add uniswap lp proposals contract address categories to mainnet - kind: ethereum name: SimpleLoanUniswapV3LPIndividualProposal network: sepolia @@ -340,7 +339,6 @@ dataSources: address,(uint256,bool,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) handler: handleProposalMade file: ./src/simple-loan-uniswap-v-3-lp-individual-proposal.ts - # TODO add uniswap lp proposals contract address categories to mainnet - kind: ethereum name: SimpleLoanUniswapV3LPSetProposal network: sepolia From 8dfa35c37e0d3404c47786301d47c1edb7ce5c43 Mon Sep 17 00:00:00 2001 From: microHoffman Date: Wed, 11 Jun 2025 14:46:31 +0200 Subject: [PATCH 08/13] test: make matchstick test setup --- bun.lockb | Bin 1362960 -> 1364048 bytes packages/subgraph/Dockerfile | 28 +++++++++++++++++++++ packages/subgraph/matchstick.yaml | 3 +++ packages/subgraph/package.json | 8 ++++-- packages/subgraph/tests/.docker/Dockerfile | 22 ++++++++++++++++ packages/subgraph/tests/.latest.json | 2 +- packages/subgraph/tests/loan-token.test.ts | 3 --- 7 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 packages/subgraph/Dockerfile create mode 100644 packages/subgraph/matchstick.yaml create mode 100644 packages/subgraph/tests/.docker/Dockerfile diff --git a/bun.lockb b/bun.lockb index 82921f137c77f1ab2b36c9fdf02305d0b8b72837..8e232c3b1cf9880ac0362e9e197896aff4c0c767 100755 GIT binary patch delta 52326 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%0AvnjM8rRRA!FKr-x1 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 J`D4LX{s)Bhv2p+a diff --git a/packages/subgraph/Dockerfile b/packages/subgraph/Dockerfile new file mode 100644 index 00000000..7ec4a548 --- /dev/null +++ b/packages/subgraph/Dockerfile @@ -0,0 +1,28 @@ +FROM --platform=linux/x86_64 ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive + +ENV ARGS="" + +RUN apt update \ + && apt install -y sudo curl postgresql postgresql-contrib + +RUN curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - \ + && sudo apt-get install -y nodejs + +RUN curl -OL https://github.com/LimeChain/matchstick/releases/download/0.6.0/binary-linux-22 \ + && chmod a+x binary-linux-22 + +WORKDIR /app + +# Copy package files +COPY package.json . +COPY package-lock.json* . + +# Install dependencies +RUN npm install + +# Copy the rest of the application +COPY . . + +CMD ../binary-linux-22 ${ARGS} diff --git a/packages/subgraph/matchstick.yaml b/packages/subgraph/matchstick.yaml new file mode 100644 index 00000000..6a7c10d0 --- /dev/null +++ b/packages/subgraph/matchstick.yaml @@ -0,0 +1,3 @@ +testsFolder: tests +libsFolder: ./node_modules +manifestPath: subgraph.yaml \ No newline at end of file diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index 04923a1b..cab73a13 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -22,12 +22,16 @@ "deploy": "nx exec -- graph deploy pwn-test-proposals subgraph.yaml", "create-local": "nx exec -- graph create --node http://localhost:8020/ pwn-test-proposals", "remove-local": "nx exec -- graph remove --node http://localhost:8020/ pwn-test-proposals", - "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals" + "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals", + "test:with-docker": "nx exec -- graph test -d", + "test": "nx exec -- graph test", + "help": "nx exec -- graph test --help" }, "dependencies": { "@graphprotocol/graph-cli": "0.97.1", "@graphprotocol/graph-ts": "0.38.1", - "mustache": "^3.1.0" + "mustache": "^3.1.0", + "matchstick-as": "0.6.0" }, "files": ["dist", "!**/*.tsbuildinfo"] } diff --git a/packages/subgraph/tests/.docker/Dockerfile b/packages/subgraph/tests/.docker/Dockerfile new file mode 100644 index 00000000..e13a03c3 --- /dev/null +++ b/packages/subgraph/tests/.docker/Dockerfile @@ -0,0 +1,22 @@ +FROM --platform=linux/x86_64 ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive + +ENV ARGS="" + +RUN apt update \ + && apt install -y sudo curl postgresql postgresql-contrib + +RUN curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - \ + && sudo apt-get install -y nodejs + +RUN curl -OL https://github.com/LimeChain/matchstick/releases/download/0.6.0/binary-linux-22 \ + && chmod a+x binary-linux-22 + +RUN mkdir matchstick +WORKDIR /matchstick + +# Commenting out for now as it seems there's no need to copy when using bind mount +# COPY ./ . + +CMD ../binary-linux-22 ${ARGS} diff --git a/packages/subgraph/tests/.latest.json b/packages/subgraph/tests/.latest.json index 6adc67ef..a4899dc7 100644 --- a/packages/subgraph/tests/.latest.json +++ b/packages/subgraph/tests/.latest.json @@ -1,4 +1,4 @@ { "version": "0.6.0", - "timestamp": 1744902689623 + "timestamp": 1749642846790 } \ No newline at end of file diff --git a/packages/subgraph/tests/loan-token.test.ts b/packages/subgraph/tests/loan-token.test.ts index c0596cd6..aba00fda 100644 --- a/packages/subgraph/tests/loan-token.test.ts +++ b/packages/subgraph/tests/loan-token.test.ts @@ -7,9 +7,6 @@ import { afterAll } from "matchstick-as/assembly/index" import { Address, BigInt } from "@graphprotocol/graph-ts" -import { Approval } from "../generated/schema" -import { Approval as ApprovalEvent } from "../generated/LoanToken/LoanToken" -import { handleApproval } from "../src/loan-token" import { createApprovalEvent } from "./loan-token-utils" // Tests structure (matchstick-as >=0.5.0) From de0018bc5623b0fcf4a11711e7fc4f1267e4989a Mon Sep 17 00:00:00 2001 From: microHoffman Date: Thu, 12 Jun 2025 01:55:38 +0200 Subject: [PATCH 09/13] test: chainlink feed registry, multi token, LOAN token --- packages/subgraph/package.json | 1 + packages/subgraph/schema.graphql | 3 +- .../subgraph/src/chainlink-feed-registry.ts | 2 +- packages/subgraph/src/loan-token.ts | 27 +- .../src/multi-token-category-registry.ts | 3 +- packages/subgraph/src/simple-loan.ts | 21 +- .../tests/chainlink-feed-registry-utils.ts | 156 +----- .../tests/chainlink-feed-registry.test.ts | 89 ++- packages/subgraph/tests/config-utils.ts | 203 ------- packages/subgraph/tests/config.test.ts | 57 -- packages/subgraph/tests/hub-utils.ts | 82 +-- packages/subgraph/tests/hub.test.ts | 82 ++- packages/subgraph/tests/loan-token-utils.ts | 126 +---- packages/subgraph/tests/loan-token.test.ts | 114 ++-- .../multi-token-category-registry-utils.ts | 111 +--- .../multi-token-category-registry.test.ts | 108 ++-- packages/subgraph/tests/proposal-utils.ts | 469 ++++++++++++++++ packages/subgraph/tests/proposal.test.ts | 431 +++++++++++++++ ...e-loan-elastic-chainlink-proposal-utils.ts | 28 - ...le-loan-elastic-chainlink-proposal.test.ts | 66 --- .../simple-loan-elastic-proposal-utils.ts | 28 - .../simple-loan-elastic-proposal.test.ts | 66 --- .../tests/simple-loan-list-proposal-utils.ts | 28 - .../tests/simple-loan-list-proposal.test.ts | 66 --- .../simple-loan-simple-proposal-utils.ts | 28 - .../tests/simple-loan-simple-proposal.test.ts | 66 --- ...niswap-v-3-lp-individual-proposal-utils.ts | 28 - ...uniswap-v-3-lp-individual-proposal.test.ts | 66 --- ...-loan-uniswap-v-3-lp-set-proposal-utils.ts | 28 - ...e-loan-uniswap-v-3-lp-set-proposal.test.ts | 66 --- packages/subgraph/tests/simple-loan-utils.ts | 508 ++++++++++-------- packages/subgraph/tests/simple-loan.test.ts | 412 ++++++++++++-- 32 files changed, 1877 insertions(+), 1692 deletions(-) delete mode 100644 packages/subgraph/tests/config-utils.ts delete mode 100644 packages/subgraph/tests/config.test.ts create mode 100644 packages/subgraph/tests/proposal-utils.ts create mode 100644 packages/subgraph/tests/proposal.test.ts delete mode 100644 packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts delete mode 100644 packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts delete mode 100644 packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts delete mode 100644 packages/subgraph/tests/simple-loan-elastic-proposal.test.ts delete mode 100644 packages/subgraph/tests/simple-loan-list-proposal-utils.ts delete mode 100644 packages/subgraph/tests/simple-loan-list-proposal.test.ts delete mode 100644 packages/subgraph/tests/simple-loan-simple-proposal-utils.ts delete mode 100644 packages/subgraph/tests/simple-loan-simple-proposal.test.ts delete mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts delete mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts delete mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts delete mode 100644 packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index cab73a13..8679e19d 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -23,6 +23,7 @@ "create-local": "nx exec -- graph create --node http://localhost:8020/ pwn-test-proposals", "remove-local": "nx exec -- graph remove --node http://localhost:8020/ pwn-test-proposals", "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals", + "docker-prepare": "docker build -t matchstick .", "test:with-docker": "nx exec -- graph test -d", "test": "nx exec -- graph test", "help": "nx exec -- graph test --help" diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 1ee77cfa..0f006c86 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -12,7 +12,7 @@ type Category @entity(immutable: true) { type AssetContract @entity(immutable: true) { id: Bytes! # asset address - category: Category! + category: Category # TODO add also metadata like name / symbol / decimals? } @@ -480,6 +480,7 @@ type LOANExtended @entity(immutable: true) { type LoanTokenTransfer @entity(immutable: true) { id: Bytes! + contractAddress: Bytes! # address from: Bytes! # address to: Bytes! # address tokenId: BigInt! # uint256 diff --git a/packages/subgraph/src/chainlink-feed-registry.ts b/packages/subgraph/src/chainlink-feed-registry.ts index 7bc58b8e..1924d5c4 100644 --- a/packages/subgraph/src/chainlink-feed-registry.ts +++ b/packages/subgraph/src/chainlink-feed-registry.ts @@ -7,7 +7,7 @@ import { import { Bytes } from "@graphprotocol/graph-ts" function getChainlinkFeedId(event: FeedConfirmedEvent): Bytes { - return event.params.asset.concatI32(event.params.denomination.toI32()) + return event.params.asset.concat(event.params.denomination) } export function handleFeedConfirmed(event: FeedConfirmedEvent): void { diff --git a/packages/subgraph/src/loan-token.ts b/packages/subgraph/src/loan-token.ts index 09531f6e..de27663b 100644 --- a/packages/subgraph/src/loan-token.ts +++ b/packages/subgraph/src/loan-token.ts @@ -10,31 +10,32 @@ import { getOrCreateAccount } from "./helpers" import { getLoanId } from "./simple-loan" export function handleTransfer(event: TransferEvent): void { - const loanTokenContract = LoanToken.bind(event.address) - const loanContractAddress = loanTokenContract.loanContract(event.params.tokenId) - - const loan = Loan.load(getLoanId(loanContractAddress, event.params.tokenId)) - - if (!loan) { - return - } - - loan.loanOwner = getOrCreateAccount(event.params.to).id - loan.save() - - const entity = new LoanTokenTransfer( event.transaction.hash.concatI32(event.logIndex.toI32()), ) entity.from = event.params.from entity.to = event.params.to entity.tokenId = event.params.tokenId + entity.contractAddress = event.address entity.blockNumber = event.block.number entity.blockTimestamp = event.block.timestamp entity.transactionHash = event.transaction.hash entity.save() + + // also update the loan owner + const loanTokenContract = LoanToken.bind(event.address) + const loanContractAddress = loanTokenContract.loanContract(event.params.tokenId) + + const loan = Loan.load(getLoanId(loanContractAddress, event.params.tokenId)) + + if (!loan) { + return + } + + loan.loanOwner = getOrCreateAccount(event.params.to).id + loan.save() } diff --git a/packages/subgraph/src/multi-token-category-registry.ts b/packages/subgraph/src/multi-token-category-registry.ts index 21a8f23e..92896e5c 100644 --- a/packages/subgraph/src/multi-token-category-registry.ts +++ b/packages/subgraph/src/multi-token-category-registry.ts @@ -47,7 +47,8 @@ export function handleCategoryUnregistered( // no need to do anything here return } - store.remove("AssetContract", event.params.assetAddress.toString()) + assetInCategory.category = null + assetInCategory.save() // TODO shall we save also the raw event? // const entity = new CategoryUnregistered( diff --git a/packages/subgraph/src/simple-loan.ts b/packages/subgraph/src/simple-loan.ts index 08d7eee3..bedfe4fc 100644 --- a/packages/subgraph/src/simple-loan.ts +++ b/packages/subgraph/src/simple-loan.ts @@ -14,12 +14,13 @@ import { } from "../generated/schema" import { getOrCreateAccount } from "./helpers" import { getOrCreateAsset } from "./utils" +import { log } from "matchstick-as/assembly/log" export function getLoanId(loanContractAddress: Address, loanId: BigInt): Bytes { return loanContractAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) } -export function handleLOANCreated(event: LOANCreatedEvent): void { +export function handleLOANCreated(event: LOANCreatedEvent): Loan { const loanId = getLoanId(event.address, event.params.loanId) const loan = new Loan(loanId) loan.loanId = event.params.loanId @@ -32,31 +33,49 @@ export function handleLOANCreated(event: LOANCreatedEvent): void { loan.borrower = getOrCreateAccount(event.params.terms.borrower).id loan.duration = event.params.terms.duration + log.info("loan.duration", []) + loan.createdAt = event.block.timestamp loan.collateral = getOrCreateAsset(event.params.terms.collateral.assetAddress, event.params.terms.collateral.id, event.params.terms.collateral.category).id loan.collateralAmount = event.params.terms.collateral.amount + + log.info("loan.collateralAmount", []) + loan.credit = getOrCreateAsset(event.params.terms.credit.assetAddress, event.params.terms.credit.id, event.params.terms.credit.category).id loan.creditAmount = event.params.terms.credit.amount + log.info("loan.collateral", []) + loan.status = "Active" loan.fixedInterestAmount = event.params.terms.fixedInterestAmount loan.accruingInterestAPR = event.params.terms.accruingInterestAPR + log.info("loan.accruingInterestAPR", []) + loan.lenderSpecHash = event.params.terms.lenderSpecHash loan.borrowerSpecHash = event.params.terms.borrowerSpecHash + log.info("loan.sourceOfFunds", []) loan.sourceOfFunds = event.params.lenderSpec.sourceOfFunds + log.info("loan.aasda", []) + loan.defaultDate = event.params.terms.duration.plus(loan.createdAt) loan.extra = event.params.extra + log.info("before contract call", []) + const simpleLoanContract = SimpleLoan.bind(Address.fromBytes(loan.contractAddress)) loan.loanTokenAddress = simpleLoanContract.loanToken() + loan.hasDefaulted = false + loan.save() + + return loan } export function handleLOANPaidBack(event: LOANPaidBackEvent): void { diff --git a/packages/subgraph/tests/chainlink-feed-registry-utils.ts b/packages/subgraph/tests/chainlink-feed-registry-utils.ts index 6e6aa1fa..83693570 100644 --- a/packages/subgraph/tests/chainlink-feed-registry-utils.ts +++ b/packages/subgraph/tests/chainlink-feed-registry-utils.ts @@ -1,153 +1,25 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Address } from "@graphprotocol/graph-ts" -import { - AccessControllerSet, - FeedConfirmed, - FeedProposed, - OwnershipTransferRequested, - OwnershipTransferred -} from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" - -export function createAccessControllerSetEvent( - accessController: Address, - sender: Address -): AccessControllerSet { - let accessControllerSetEvent = changetype(newMockEvent()) - - accessControllerSetEvent.parameters = new Array() - - accessControllerSetEvent.parameters.push( - new ethereum.EventParam( - "accessController", - ethereum.Value.fromAddress(accessController) - ) - ) - accessControllerSetEvent.parameters.push( - new ethereum.EventParam("sender", ethereum.Value.fromAddress(sender)) - ) - - return accessControllerSetEvent -} +import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" +import { FeedConfirmed } from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" +import { assert, test, newMockEvent, dataSourceMock } from 'matchstick-as/assembly/index' export function createFeedConfirmedEvent( asset: Address, denomination: Address, - latestAggregator: Address, - previousAggregator: Address, - nextPhaseId: i32, - sender: Address + latestAggregator: Address ): FeedConfirmed { - let feedConfirmedEvent = changetype(newMockEvent()) - - feedConfirmedEvent.parameters = new Array() - - feedConfirmedEvent.parameters.push( + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( new ethereum.EventParam("asset", ethereum.Value.fromAddress(asset)) ) - feedConfirmedEvent.parameters.push( - new ethereum.EventParam( - "denomination", - ethereum.Value.fromAddress(denomination) - ) - ) - feedConfirmedEvent.parameters.push( - new ethereum.EventParam( - "latestAggregator", - ethereum.Value.fromAddress(latestAggregator) - ) - ) - feedConfirmedEvent.parameters.push( - new ethereum.EventParam( - "previousAggregator", - ethereum.Value.fromAddress(previousAggregator) - ) - ) - feedConfirmedEvent.parameters.push( - new ethereum.EventParam( - "nextPhaseId", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(nextPhaseId)) - ) - ) - feedConfirmedEvent.parameters.push( - new ethereum.EventParam("sender", ethereum.Value.fromAddress(sender)) - ) - - return feedConfirmedEvent -} - -export function createFeedProposedEvent( - asset: Address, - denomination: Address, - proposedAggregator: Address, - currentAggregator: Address, - sender: Address -): FeedProposed { - let feedProposedEvent = changetype(newMockEvent()) - - feedProposedEvent.parameters = new Array() - - feedProposedEvent.parameters.push( - new ethereum.EventParam("asset", ethereum.Value.fromAddress(asset)) - ) - feedProposedEvent.parameters.push( - new ethereum.EventParam( - "denomination", - ethereum.Value.fromAddress(denomination) - ) - ) - feedProposedEvent.parameters.push( - new ethereum.EventParam( - "proposedAggregator", - ethereum.Value.fromAddress(proposedAggregator) - ) - ) - feedProposedEvent.parameters.push( - new ethereum.EventParam( - "currentAggregator", - ethereum.Value.fromAddress(currentAggregator) - ) - ) - feedProposedEvent.parameters.push( - new ethereum.EventParam("sender", ethereum.Value.fromAddress(sender)) - ) - - return feedProposedEvent -} - -export function createOwnershipTransferRequestedEvent( - from: Address, - to: Address -): OwnershipTransferRequested { - let ownershipTransferRequestedEvent = - changetype(newMockEvent()) - - ownershipTransferRequestedEvent.parameters = new Array() - - ownershipTransferRequestedEvent.parameters.push( - new ethereum.EventParam("from", ethereum.Value.fromAddress(from)) - ) - ownershipTransferRequestedEvent.parameters.push( - new ethereum.EventParam("to", ethereum.Value.fromAddress(to)) - ) - - return ownershipTransferRequestedEvent -} - -export function createOwnershipTransferredEvent( - from: Address, - to: Address -): OwnershipTransferred { - let ownershipTransferredEvent = - changetype(newMockEvent()) - - ownershipTransferredEvent.parameters = new Array() - - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam("from", ethereum.Value.fromAddress(from)) + event.parameters.push( + new ethereum.EventParam("denomination", ethereum.Value.fromAddress(denomination)) ) - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam("to", ethereum.Value.fromAddress(to)) + event.parameters.push( + new ethereum.EventParam("latestAggregator", ethereum.Value.fromAddress(latestAggregator)) ) - return ownershipTransferredEvent + return event } diff --git a/packages/subgraph/tests/chainlink-feed-registry.test.ts b/packages/subgraph/tests/chainlink-feed-registry.test.ts index 59757679..b4ba88a8 100644 --- a/packages/subgraph/tests/chainlink-feed-registry.test.ts +++ b/packages/subgraph/tests/chainlink-feed-registry.test.ts @@ -1,60 +1,55 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Address } from "@graphprotocol/graph-ts" -import { AccessControllerSet } from "../generated/schema" -import { AccessControllerSet as AccessControllerSetEvent } from "../generated/ChainlinkFeedRegistry/ChainlinkFeedRegistry" -import { handleAccessControllerSet } from "../src/chainlink-feed-registry" -import { createAccessControllerSetEvent } from "./chainlink-feed-registry-utils" +import { assert, describe, test, clearStore, beforeEach, afterEach } from "matchstick-as/assembly/index" +import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" +import { handleFeedConfirmed } from "../src/chainlink-feed-registry" +import { createFeedConfirmedEvent } from "./chainlink-feed-registry-utils" -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let accessController = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let sender = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let newAccessControllerSetEvent = createAccessControllerSetEvent( - accessController, - sender - ) - handleAccessControllerSet(newAccessControllerSetEvent) +describe("ChainlinkFeedRegistry", () => { + beforeEach(() => { + clearStore() }) - afterAll(() => { + afterEach(() => { clearStore() }) - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + test("handleFeedConfirmed - creates a new ChainlinkFeed entity", () => { + // Create test data + const asset = Address.fromString("0x0000000000000000000000000000000000000001") + const denomination = Address.fromString("0x0000000000000000000000000000000000000002") + const latestAggregator = Address.fromString("0x0000000000000000000000000000000000000003") + + // Create the event + const event = createFeedConfirmedEvent( + asset, + denomination, + latestAggregator + ) + + // Handle the event + handleFeedConfirmed(event) - test("AccessControllerSet created and stored", () => { - assert.entityCount("AccessControllerSet", 1) + // Get the expected ID + const chainlinkFeedId = asset.concat(denomination) - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + // Assert the ChainlinkFeed entity was created with correct data + assert.entityCount("ChainlinkFeed", 1) assert.fieldEquals( - "AccessControllerSet", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "accessController", - "0x0000000000000000000000000000000000000001" + "ChainlinkFeed", + chainlinkFeedId.toHexString(), + "asset", + asset.toHexString() ) assert.fieldEquals( - "AccessControllerSet", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "sender", - "0x0000000000000000000000000000000000000001" + "ChainlinkFeed", + chainlinkFeedId.toHexString(), + "denomination", + denomination.toHexString() + ) + assert.fieldEquals( + "ChainlinkFeed", + chainlinkFeedId.toHexString(), + "aggregator", + latestAggregator.toHexString() ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts }) -}) +}) \ No newline at end of file diff --git a/packages/subgraph/tests/config-utils.ts b/packages/subgraph/tests/config-utils.ts deleted file mode 100644 index 3241e3c0..00000000 --- a/packages/subgraph/tests/config-utils.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Address } from "@graphprotocol/graph-ts" -import { - AdminChanged, - BeaconUpgraded, - Upgraded, - DefaultLOANMetadataUriUpdated, - FeeCollectorUpdated, - FeeUpdated, - Initialized, - LOANMetadataUriUpdated, - OwnershipTransferStarted, - OwnershipTransferred -} from "../generated/Config/Config" - -export function createAdminChangedEvent( - previousAdmin: Address, - newAdmin: Address -): AdminChanged { - let adminChangedEvent = changetype(newMockEvent()) - - adminChangedEvent.parameters = new Array() - - adminChangedEvent.parameters.push( - new ethereum.EventParam( - "previousAdmin", - ethereum.Value.fromAddress(previousAdmin) - ) - ) - adminChangedEvent.parameters.push( - new ethereum.EventParam("newAdmin", ethereum.Value.fromAddress(newAdmin)) - ) - - return adminChangedEvent -} - -export function createBeaconUpgradedEvent(beacon: Address): BeaconUpgraded { - let beaconUpgradedEvent = changetype(newMockEvent()) - - beaconUpgradedEvent.parameters = new Array() - - beaconUpgradedEvent.parameters.push( - new ethereum.EventParam("beacon", ethereum.Value.fromAddress(beacon)) - ) - - return beaconUpgradedEvent -} - -export function createUpgradedEvent(implementation: Address): Upgraded { - let upgradedEvent = changetype(newMockEvent()) - - upgradedEvent.parameters = new Array() - - upgradedEvent.parameters.push( - new ethereum.EventParam( - "implementation", - ethereum.Value.fromAddress(implementation) - ) - ) - - return upgradedEvent -} - -export function createDefaultLOANMetadataUriUpdatedEvent( - newUri: string -): DefaultLOANMetadataUriUpdated { - let defaultLoanMetadataUriUpdatedEvent = - changetype(newMockEvent()) - - defaultLoanMetadataUriUpdatedEvent.parameters = new Array() - - defaultLoanMetadataUriUpdatedEvent.parameters.push( - new ethereum.EventParam("newUri", ethereum.Value.fromString(newUri)) - ) - - return defaultLoanMetadataUriUpdatedEvent -} - -export function createFeeCollectorUpdatedEvent( - oldFeeCollector: Address, - newFeeCollector: Address -): FeeCollectorUpdated { - let feeCollectorUpdatedEvent = changetype(newMockEvent()) - - feeCollectorUpdatedEvent.parameters = new Array() - - feeCollectorUpdatedEvent.parameters.push( - new ethereum.EventParam( - "oldFeeCollector", - ethereum.Value.fromAddress(oldFeeCollector) - ) - ) - feeCollectorUpdatedEvent.parameters.push( - new ethereum.EventParam( - "newFeeCollector", - ethereum.Value.fromAddress(newFeeCollector) - ) - ) - - return feeCollectorUpdatedEvent -} - -export function createFeeUpdatedEvent(oldFee: i32, newFee: i32): FeeUpdated { - let feeUpdatedEvent = changetype(newMockEvent()) - - feeUpdatedEvent.parameters = new Array() - - feeUpdatedEvent.parameters.push( - new ethereum.EventParam( - "oldFee", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(oldFee)) - ) - ) - feeUpdatedEvent.parameters.push( - new ethereum.EventParam( - "newFee", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(newFee)) - ) - ) - - return feeUpdatedEvent -} - -export function createInitializedEvent(version: i32): Initialized { - let initializedEvent = changetype(newMockEvent()) - - initializedEvent.parameters = new Array() - - initializedEvent.parameters.push( - new ethereum.EventParam( - "version", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(version)) - ) - ) - - return initializedEvent -} - -export function createLOANMetadataUriUpdatedEvent( - loanContract: Address, - newUri: string -): LOANMetadataUriUpdated { - let loanMetadataUriUpdatedEvent = - changetype(newMockEvent()) - - loanMetadataUriUpdatedEvent.parameters = new Array() - - loanMetadataUriUpdatedEvent.parameters.push( - new ethereum.EventParam( - "loanContract", - ethereum.Value.fromAddress(loanContract) - ) - ) - loanMetadataUriUpdatedEvent.parameters.push( - new ethereum.EventParam("newUri", ethereum.Value.fromString(newUri)) - ) - - return loanMetadataUriUpdatedEvent -} - -export function createOwnershipTransferStartedEvent( - previousOwner: Address, - newOwner: Address -): OwnershipTransferStarted { - let ownershipTransferStartedEvent = - changetype(newMockEvent()) - - ownershipTransferStartedEvent.parameters = new Array() - - ownershipTransferStartedEvent.parameters.push( - new ethereum.EventParam( - "previousOwner", - ethereum.Value.fromAddress(previousOwner) - ) - ) - ownershipTransferStartedEvent.parameters.push( - new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) - ) - - return ownershipTransferStartedEvent -} - -export function createOwnershipTransferredEvent( - previousOwner: Address, - newOwner: Address -): OwnershipTransferred { - let ownershipTransferredEvent = - changetype(newMockEvent()) - - ownershipTransferredEvent.parameters = new Array() - - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam( - "previousOwner", - ethereum.Value.fromAddress(previousOwner) - ) - ) - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) - ) - - return ownershipTransferredEvent -} diff --git a/packages/subgraph/tests/config.test.ts b/packages/subgraph/tests/config.test.ts deleted file mode 100644 index 90e2beb9..00000000 --- a/packages/subgraph/tests/config.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Address } from "@graphprotocol/graph-ts" -import { AdminChanged } from "../generated/schema" -import { AdminChanged as AdminChangedEvent } from "../generated/Config/Config" -import { handleAdminChanged } from "../src/config" -import { createAdminChangedEvent } from "./config-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let previousAdmin = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let newAdmin = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let newAdminChangedEvent = createAdminChangedEvent(previousAdmin, newAdmin) - handleAdminChanged(newAdminChangedEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("AdminChanged created and stored", () => { - assert.entityCount("AdminChanged", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "AdminChanged", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "previousAdmin", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "AdminChanged", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "newAdmin", - "0x0000000000000000000000000000000000000001" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/hub-utils.ts b/packages/subgraph/tests/hub-utils.ts index c618cf7d..1ffcfc71 100644 --- a/packages/subgraph/tests/hub-utils.ts +++ b/packages/subgraph/tests/hub-utils.ts @@ -1,73 +1,27 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Address, Bytes } from "@graphprotocol/graph-ts" -import { - OwnershipTransferStarted, - OwnershipTransferred, - TagSet -} from "../generated/Hub/Hub" - -export function createOwnershipTransferStartedEvent( - previousOwner: Address, - newOwner: Address -): OwnershipTransferStarted { - let ownershipTransferStartedEvent = - changetype(newMockEvent()) - - ownershipTransferStartedEvent.parameters = new Array() - - ownershipTransferStartedEvent.parameters.push( - new ethereum.EventParam( - "previousOwner", - ethereum.Value.fromAddress(previousOwner) - ) - ) - ownershipTransferStartedEvent.parameters.push( - new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) - ) - - return ownershipTransferStartedEvent -} - -export function createOwnershipTransferredEvent( - previousOwner: Address, - newOwner: Address -): OwnershipTransferred { - let ownershipTransferredEvent = - changetype(newMockEvent()) - - ownershipTransferredEvent.parameters = new Array() - - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam( - "previousOwner", - ethereum.Value.fromAddress(previousOwner) - ) - ) - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) - ) - - return ownershipTransferredEvent -} +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts" +import { TagSet } from "../generated/Hub/Hub" +import { assert, test, newMockEvent } from 'matchstick-as/assembly/index' export function createTagSetEvent( - _address: Address, + contractAddress: Address, tag: Bytes, hasTag: boolean ): TagSet { - let tagSetEvent = changetype(newMockEvent()) - - tagSetEvent.parameters = new Array() - - tagSetEvent.parameters.push( - new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address)) + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("_address", ethereum.Value.fromAddress(contractAddress)) ) - tagSetEvent.parameters.push( - new ethereum.EventParam("tag", ethereum.Value.fromFixedBytes(tag)) + event.parameters.push( + new ethereum.EventParam("tag", ethereum.Value.fromBytes(tag)) ) - tagSetEvent.parameters.push( + event.parameters.push( new ethereum.EventParam("hasTag", ethereum.Value.fromBoolean(hasTag)) ) - - return tagSetEvent -} + + event.address = Address.fromString("0x0000000000000000000000000000000000000001") + + return event +} \ No newline at end of file diff --git a/packages/subgraph/tests/hub.test.ts b/packages/subgraph/tests/hub.test.ts index 221f5433..10bb7bc8 100644 --- a/packages/subgraph/tests/hub.test.ts +++ b/packages/subgraph/tests/hub.test.ts @@ -1,60 +1,48 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Address, Bytes } from "@graphprotocol/graph-ts" -import { OwnershipTransferStarted } from "../generated/schema" -import { OwnershipTransferStarted as OwnershipTransferStartedEvent } from "../generated/Hub/Hub" -import { handleOwnershipTransferStarted } from "../src/hub" -import { createOwnershipTransferStartedEvent } from "./hub-utils" +import { assert, describe, test, clearStore, beforeEach, afterEach } from "matchstick-as/assembly/index" +import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" +import { handleTagSet } from "../src/hub" +import { createTagSetEvent } from "./hub-utils" -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let previousOwner = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let newOwner = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let newOwnershipTransferStartedEvent = createOwnershipTransferStartedEvent( - previousOwner, - newOwner - ) - handleOwnershipTransferStarted(newOwnershipTransferStartedEvent) +describe("Hub Events", () => { + beforeEach(() => { + // Clear the store before each test + clearStore() }) - afterAll(() => { + afterEach(() => { + // Clear the store after each test clearStore() }) - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + test("handleTagSet - creates a new Tag entity", () => { + let tag = Bytes.fromHexString("0x1234") + let value = true + let contractAddress = Address.fromString("0x0000000000000000000000000000000000000001") - test("OwnershipTransferStarted created and stored", () => { - assert.entityCount("OwnershipTransferStarted", 1) + let event = createTagSetEvent(contractAddress, tag, value) - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + handleTagSet(event) + + const tagSetId: Bytes = event.transaction.hash.concatI32(event.logIndex.toI32()) + + assert.entityCount("TagSet", 1) assert.fieldEquals( - "OwnershipTransferStarted", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "previousOwner", - "0x0000000000000000000000000000000000000001" + "TagSet", + tagSetId.toHexString(), + "tag", + tag.toHexString() ) assert.fieldEquals( - "OwnershipTransferStarted", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "newOwner", - "0x0000000000000000000000000000000000000001" + "TagSet", + tagSetId.toHexString(), + "hasTag", + value.toString(), + ) + assert.fieldEquals( + "TagSet", + tagSetId.toHexString(), + "_address", + contractAddress.toHexString() ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts }) -}) +}) \ No newline at end of file diff --git a/packages/subgraph/tests/loan-token-utils.ts b/packages/subgraph/tests/loan-token-utils.ts index 489cf282..546fe9cd 100644 --- a/packages/subgraph/tests/loan-token-utils.ts +++ b/packages/subgraph/tests/loan-token-utils.ts @@ -1,118 +1,28 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Address, BigInt } from "@graphprotocol/graph-ts" -import { - Approval, - ApprovalForAll, - LOANBurned, - LOANMinted, - Transfer -} from "../generated/LoanToken/LoanToken" - -export function createApprovalEvent( - owner: Address, - approved: Address, - tokenId: BigInt -): Approval { - let approvalEvent = changetype(newMockEvent()) - - approvalEvent.parameters = new Array() - - approvalEvent.parameters.push( - new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) - ) - approvalEvent.parameters.push( - new ethereum.EventParam("approved", ethereum.Value.fromAddress(approved)) - ) - approvalEvent.parameters.push( - new ethereum.EventParam( - "tokenId", - ethereum.Value.fromUnsignedBigInt(tokenId) - ) - ) - - return approvalEvent -} - -export function createApprovalForAllEvent( - owner: Address, - operator: Address, - approved: boolean -): ApprovalForAll { - let approvalForAllEvent = changetype(newMockEvent()) - - approvalForAllEvent.parameters = new Array() - - approvalForAllEvent.parameters.push( - new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) - ) - approvalForAllEvent.parameters.push( - new ethereum.EventParam("operator", ethereum.Value.fromAddress(operator)) - ) - approvalForAllEvent.parameters.push( - new ethereum.EventParam("approved", ethereum.Value.fromBoolean(approved)) - ) - - return approvalForAllEvent -} - -export function createLOANBurnedEvent(loanId: BigInt): LOANBurned { - let loanBurnedEvent = changetype(newMockEvent()) - - loanBurnedEvent.parameters = new Array() - - loanBurnedEvent.parameters.push( - new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) - ) - - return loanBurnedEvent -} - -export function createLOANMintedEvent( - loanId: BigInt, - loanContract: Address, - owner: Address -): LOANMinted { - let loanMintedEvent = changetype(newMockEvent()) - - loanMintedEvent.parameters = new Array() - - loanMintedEvent.parameters.push( - new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) - ) - loanMintedEvent.parameters.push( - new ethereum.EventParam( - "loanContract", - ethereum.Value.fromAddress(loanContract) - ) - ) - loanMintedEvent.parameters.push( - new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) - ) - - return loanMintedEvent -} +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts" +import { Transfer } from "../generated/LoanToken/LoanToken" +import { assert, test, newMockEvent } from 'matchstick-as/assembly/index' export function createTransferEvent( from: Address, to: Address, - tokenId: BigInt + tokenId: BigInt, + loanTokenAddress: Address ): Transfer { - let transferEvent = changetype(newMockEvent()) - - transferEvent.parameters = new Array() - - transferEvent.parameters.push( + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( new ethereum.EventParam("from", ethereum.Value.fromAddress(from)) ) - transferEvent.parameters.push( + event.parameters.push( new ethereum.EventParam("to", ethereum.Value.fromAddress(to)) ) - transferEvent.parameters.push( - new ethereum.EventParam( - "tokenId", - ethereum.Value.fromUnsignedBigInt(tokenId) - ) + event.parameters.push( + new ethereum.EventParam("tokenId", ethereum.Value.fromUnsignedBigInt(tokenId)) ) - - return transferEvent -} + + event.address = loanTokenAddress + + return event +} \ No newline at end of file diff --git a/packages/subgraph/tests/loan-token.test.ts b/packages/subgraph/tests/loan-token.test.ts index aba00fda..d727b9ce 100644 --- a/packages/subgraph/tests/loan-token.test.ts +++ b/packages/subgraph/tests/loan-token.test.ts @@ -1,59 +1,85 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Address, BigInt } from "@graphprotocol/graph-ts" -import { createApprovalEvent } from "./loan-token-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let owner = Address.fromString("0x0000000000000000000000000000000000000001") - let approved = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let tokenId = BigInt.fromI32(234) - let newApprovalEvent = createApprovalEvent(owner, approved, tokenId) - handleApproval(newApprovalEvent) +import { assert, describe, test, clearStore, beforeEach, afterEach, createMockedFunction } from "matchstick-as/assembly/index" +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts" +import { handleTransfer } from "../src/loan-token" +import { createTransferEvent } from "./loan-token-utils" +import { getLoanId } from "../src/simple-loan" +import { Loan } from "../generated/schema" +import { createDefaultTestLoan, TestLoanParams } from "./simple-loan-utils" +import { log } from "matchstick-as/assembly/log" + +describe("LoanToken Events", () => { + beforeEach(() => { + // Clear the store before each test + clearStore() }) - afterAll(() => { + afterEach(() => { + // Clear the store after each test clearStore() }) - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + test("handleTransfer - creates a new Transfer entity", () => { + let from = Address.fromString("0x0000000000000000000000000000000000000001") + let to = Address.fromString("0x0000000000000000000000000000000000000002") + let tokenId = BigInt.fromI32(100) + let loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000003") + // default address used in mocks in matchstick-as/assembly/defaults.ts + let loanContractAddress = Address.fromString("0xA16081F360e3847006dB660bae1c6d1b2e17eC2A") + + // create mock loan entity + const loanId = getLoanId(loanContractAddress, tokenId) + const loanParams = new TestLoanParams() + loanParams.loanTokenAddress = loanTokenAddress + loanParams.lender = from + + createMockedFunction(loanContractAddress, 'loanToken', 'loanToken():(address)') + .returns([ethereum.Value.fromAddress(loanTokenAddress)]) + + log.info("before createDefaultTestLoan", []) + createDefaultTestLoan(tokenId, loanParams) + log.info("after createDefaultTestLoan", []) + assert.fieldEquals("Loan", loanId.toHexString(), "loanOwner", from.toHexString()) + + log.info("before createTransferEvent", []) + let event = createTransferEvent(from, to, tokenId, loanTokenAddress) + log.info("after createTransferEvent", []) + const transferEventId = event.transaction.hash.concatI32(event.logIndex.toI32()) - test("Approval created and stored", () => { - assert.entityCount("Approval", 1) + createMockedFunction(loanTokenAddress, 'loanContract', 'loanContract(uint256):(address)') + .withArgs([ethereum.Value.fromUnsignedBigInt(event.params.tokenId)]) + .returns([ethereum.Value.fromAddress(loanContractAddress)]) - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + log.info("before handleTransfer", []) + handleTransfer(event) + + log.info("after handleTransfer", []) + + assert.fieldEquals("Loan", loanId.toHexString(), "loanOwner", to.toHexString()) + + assert.entityCount("LoanTokenTransfer", 1) assert.fieldEquals( - "Approval", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "owner", - "0x0000000000000000000000000000000000000001" + "LoanTokenTransfer", + transferEventId.toHexString(), + "from", + from.toHexString() ) assert.fieldEquals( - "Approval", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "approved", - "0x0000000000000000000000000000000000000001" + "LoanTokenTransfer", + transferEventId.toHexString(), + "to", + to.toHexString() ) assert.fieldEquals( - "Approval", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "LoanTokenTransfer", + transferEventId.toHexString(), "tokenId", - "234" + tokenId.toString() + ) + assert.fieldEquals( + "LoanTokenTransfer", + transferEventId.toHexString(), + "contractAddress", + loanTokenAddress.toHexString() ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts }) -}) +}) \ No newline at end of file diff --git a/packages/subgraph/tests/multi-token-category-registry-utils.ts b/packages/subgraph/tests/multi-token-category-registry-utils.ts index 82206210..9fd82fd0 100644 --- a/packages/subgraph/tests/multi-token-category-registry-utils.ts +++ b/packages/subgraph/tests/multi-token-category-registry-utils.ts @@ -1,94 +1,39 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Address } from "@graphprotocol/graph-ts" -import { - CategoryRegistered, - CategoryUnregistered, - OwnershipTransferStarted, - OwnershipTransferred -} from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts" +import { CategoryRegistered, CategoryUnregistered } from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" +import { assert, test, newMockEvent } from 'matchstick-as/assembly/index' export function createCategoryRegisteredEvent( - assetAddress: Address, + asset: Address, category: i32 ): CategoryRegistered { - let categoryRegisteredEvent = changetype(newMockEvent()) - - categoryRegisteredEvent.parameters = new Array() - - categoryRegisteredEvent.parameters.push( - new ethereum.EventParam( - "assetAddress", - ethereum.Value.fromAddress(assetAddress) - ) + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("assetAddress", ethereum.Value.fromAddress(asset)) ) - categoryRegisteredEvent.parameters.push( - new ethereum.EventParam( - "category", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(category)) - ) + event.parameters.push( + new ethereum.EventParam("category", ethereum.Value.fromI32(category)) ) - - return categoryRegisteredEvent + + event.address = Address.fromString("0x0000000000000000000000000000000000000001") + + return event } export function createCategoryUnregisteredEvent( - assetAddress: Address + asset: Address ): CategoryUnregistered { - let categoryUnregisteredEvent = - changetype(newMockEvent()) - - categoryUnregisteredEvent.parameters = new Array() - - categoryUnregisteredEvent.parameters.push( - new ethereum.EventParam( - "assetAddress", - ethereum.Value.fromAddress(assetAddress) - ) - ) - - return categoryUnregisteredEvent -} - -export function createOwnershipTransferStartedEvent( - previousOwner: Address, - newOwner: Address -): OwnershipTransferStarted { - let ownershipTransferStartedEvent = - changetype(newMockEvent()) - - ownershipTransferStartedEvent.parameters = new Array() - - ownershipTransferStartedEvent.parameters.push( - new ethereum.EventParam( - "previousOwner", - ethereum.Value.fromAddress(previousOwner) - ) + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("assetAddress", ethereum.Value.fromAddress(asset)) ) - ownershipTransferStartedEvent.parameters.push( - new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) - ) - - return ownershipTransferStartedEvent -} - -export function createOwnershipTransferredEvent( - previousOwner: Address, - newOwner: Address -): OwnershipTransferred { - let ownershipTransferredEvent = - changetype(newMockEvent()) - - ownershipTransferredEvent.parameters = new Array() - - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam( - "previousOwner", - ethereum.Value.fromAddress(previousOwner) - ) - ) - ownershipTransferredEvent.parameters.push( - new ethereum.EventParam("newOwner", ethereum.Value.fromAddress(newOwner)) - ) - - return ownershipTransferredEvent -} + + event.address = Address.fromString("0x0000000000000000000000000000000000000001") + + return event +} \ No newline at end of file diff --git a/packages/subgraph/tests/multi-token-category-registry.test.ts b/packages/subgraph/tests/multi-token-category-registry.test.ts index 89533e16..3acde73b 100644 --- a/packages/subgraph/tests/multi-token-category-registry.test.ts +++ b/packages/subgraph/tests/multi-token-category-registry.test.ts @@ -1,58 +1,78 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Address } from "@graphprotocol/graph-ts" -import { CategoryRegistered } from "../generated/schema" -import { CategoryRegistered as CategoryRegisteredEvent } from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" -import { handleCategoryRegistered } from "../src/multi-token-category-registry" -import { createCategoryRegisteredEvent } from "./multi-token-category-registry-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let assetAddress = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let category = 123 - let newCategoryRegisteredEvent = createCategoryRegisteredEvent( - assetAddress, - category - ) - handleCategoryRegistered(newCategoryRegisteredEvent) +import { assert, describe, test, clearStore, beforeEach, afterEach } from "matchstick-as/assembly/index" +import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" +import { handleCategoryRegistered, handleCategoryUnregistered } from "../src/multi-token-category-registry" +import { createCategoryRegisteredEvent, createCategoryUnregisteredEvent } from "./multi-token-category-registry-utils" +import { AssetContract } from "../generated/schema" +import { log } from "matchstick-as/assembly/log"; +import { logStore, logEntity } from 'matchstick-as/assembly/store' + +describe("MultiTokenCategoryRegistry Events", () => { + beforeEach(() => { + // Clear the store before each test + clearStore() }) - afterAll(() => { + afterEach(() => { + // Clear the store after each test clearStore() }) - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + test("handleCategoryRegistered - creates a new Category entity", () => { + let category = Bytes.fromHexString("0x1234").toI32() + let assetAddress = Address.fromString("0x0000000000000000000000000000000000000001") - test("CategoryRegistered created and stored", () => { - assert.entityCount("CategoryRegistered", 1) + let event = createCategoryRegisteredEvent(assetAddress, category) - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + handleCategoryRegistered(event) + + let categoryId = Bytes.fromI32(category).toHexString() + + assert.entityCount("Category", 1) + assert.fieldEquals( + "Category", + categoryId, + "id", + categoryId + ) + assert.entityCount("AssetContract", 1) assert.fieldEquals( - "CategoryRegistered", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "assetAddress", - "0x0000000000000000000000000000000000000001" + "AssetContract", + assetAddress.toHexString(), + "id", + assetAddress.toHexString() ) + assert.fieldEquals( - "CategoryRegistered", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + "AssetContract", + assetAddress.toHexString(), "category", - "123" + categoryId ) + }) + + test("handleCategoryUnregistered - removes the Category entity", () => { + let category = Bytes.fromHexString("0x1234").toI32() + let registryAddress = Address.fromString("0x0000000000000000000000000000000000000001") + + // First register the category + let registerEvent = createCategoryRegisteredEvent(registryAddress, category) + handleCategoryRegistered(registerEvent) + + // Then unregister it + let unregisterEvent = createCategoryUnregisteredEvent(registryAddress) + handleCategoryUnregistered(unregisterEvent) + + assert.entityCount("Category", 1) + assert.entityCount("AssetContract", 1) + const assetContract = AssetContract.load(Bytes.fromHexString(registryAddress.toHexString())) + assert.assertNotNull(assetContract) - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + if (assetContract != null) { + let assetCategory = assetContract.get("category") + // note: for some reason we can't use assert.assertNull here as here it's stringied "null", + // but this should be good enough for now + assert.fieldEquals("AssetContract", registryAddress.toHexString(), "category", "null") + } + // TODO shall we throw an error if the asset contract is not found? }) -}) +}) \ No newline at end of file diff --git a/packages/subgraph/tests/proposal-utils.ts b/packages/subgraph/tests/proposal-utils.ts new file mode 100644 index 00000000..5d435442 --- /dev/null +++ b/packages/subgraph/tests/proposal-utils.ts @@ -0,0 +1,469 @@ +import { Address, BigInt, ByteArray, Bytes, ethereum } from "@graphprotocol/graph-ts" +import { ProposalMade } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" +import { ProposalMade as ListProposalMade } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" +import { ProposalMade as ElasticProposalMade } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" +import { ProposalMade as ElasticChainlinkProposalMade } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" +import { ProposalMade as UniswapV3LPIndividualProposalMade } from "../generated/SimpleLoanUniswapV3LPIndividualProposal/SimpleLoanUniswapV3LPIndividualProposal" +import { ProposalMade as UniswapV3LPSetProposalMade } from "../generated/SimpleLoanUniswapV3LPSetProposal/SimpleLoanUniswapV3LPSetProposal" +import { assert, test, newMockEvent, dataSourceMock } from 'matchstick-as/assembly/index' + +export function createSimpleProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + collateralCategory: i32, + collateralAddress: Address, + collateralId: BigInt, + collateralAmount: BigInt, + checkCollateralStateFingerprint: boolean, + collateralStateFingerprint: Bytes, + creditAddress: Address, + creditAmount: BigInt, + availableCreditLimit: BigInt, + utilizedCreditId: Bytes, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + durationOrDate: BigInt, + expiration: BigInt, + allowedAcceptor: Address, + proposerSpecHash: Bytes, + isOffer: boolean, + refinancingLoanId: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanContract: Address +): ProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) + ) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + + let proposalTuple = new ethereum.Tuple() + proposalTuple.push(ethereum.Value.fromI32(collateralCategory)) + proposalTuple.push(ethereum.Value.fromAddress(collateralAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralAmount)) + proposalTuple.push(ethereum.Value.fromBoolean(checkCollateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromBytes(collateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromAddress(creditAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(creditAmount)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(availableCreditLimit)) + proposalTuple.push(ethereum.Value.fromBytes(utilizedCreditId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + proposalTuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(durationOrDate)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + proposalTuple.push(ethereum.Value.fromAddress(allowedAcceptor)) + proposalTuple.push(ethereum.Value.fromAddress(proposer)) + proposalTuple.push(ethereum.Value.fromBytes(proposerSpecHash)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + proposalTuple.push(ethereum.Value.fromAddress(loanContract)) + + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposalTuple)) + ) + + event.address = loanContract + + return event +} + +export function createListProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + collateralCategory: i32, + collateralAddress: Address, + collateralIdsWhitelistMerkleRoot: Bytes, + collateralAmount: BigInt, + checkCollateralStateFingerprint: boolean, + collateralStateFingerprint: Bytes, + creditAddress: Address, + creditAmount: BigInt, + availableCreditLimit: BigInt, + utilizedCreditId: Bytes, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + durationOrDate: BigInt, + expiration: BigInt, + allowedAcceptor: Address, + proposerSpecHash: Bytes, + isOffer: boolean, + refinancingLoanId: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanContract: Address +): ListProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) + ) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + + let proposalTuple = new ethereum.Tuple() + proposalTuple.push(ethereum.Value.fromI32(collateralCategory)) + proposalTuple.push(ethereum.Value.fromAddress(collateralAddress)) + proposalTuple.push(ethereum.Value.fromBytes(collateralIdsWhitelistMerkleRoot)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralAmount)) + proposalTuple.push(ethereum.Value.fromBoolean(checkCollateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromBytes(collateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromAddress(creditAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(creditAmount)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(availableCreditLimit)) + proposalTuple.push(ethereum.Value.fromBytes(utilizedCreditId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + proposalTuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(durationOrDate)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + proposalTuple.push(ethereum.Value.fromAddress(allowedAcceptor)) + proposalTuple.push(ethereum.Value.fromAddress(proposer)) + proposalTuple.push(ethereum.Value.fromBytes(proposerSpecHash)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + proposalTuple.push(ethereum.Value.fromAddress(loanContract)) + + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposalTuple)) + ) + + event.address = loanContract + + return event +} + +export function createElasticProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + collateralCategory: i32, + collateralAddress: Address, + collateralId: BigInt, + checkCollateralStateFingerprint: boolean, + collateralStateFingerprint: Bytes, + creditAddress: Address, + creditPerCollateralUnit: BigInt, + minCreditAmount: BigInt, + availableCreditLimit: BigInt, + utilizedCreditId: Bytes, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + durationOrDate: BigInt, + expiration: BigInt, + allowedAcceptor: Address, + proposerSpecHash: Bytes, + isOffer: boolean, + refinancingLoanId: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanContract: Address +): ElasticProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) + ) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + + let proposalTuple = new ethereum.Tuple() + proposalTuple.push(ethereum.Value.fromI32(collateralCategory)) + proposalTuple.push(ethereum.Value.fromAddress(collateralAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralId)) + proposalTuple.push(ethereum.Value.fromBoolean(checkCollateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromBytes(collateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromAddress(creditAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(creditPerCollateralUnit)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(minCreditAmount)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(availableCreditLimit)) + proposalTuple.push(ethereum.Value.fromBytes(utilizedCreditId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + proposalTuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(durationOrDate)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + proposalTuple.push(ethereum.Value.fromAddress(allowedAcceptor)) + proposalTuple.push(ethereum.Value.fromAddress(proposer)) + proposalTuple.push(ethereum.Value.fromBytes(proposerSpecHash)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + proposalTuple.push(ethereum.Value.fromAddress(loanContract)) + + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposalTuple)) + ) + + event.address = loanContract + + return event +} + +export function createElasticChainlinkProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + collateralCategory: i32, + collateralAddress: Address, + collateralId: BigInt, + checkCollateralStateFingerprint: boolean, + collateralStateFingerprint: Bytes, + creditAddress: Address, + feedIntermediaryDenominations: Bytes[], + feedInvertFlags: boolean[], + loanToValue: BigInt, + minCreditAmount: BigInt, + availableCreditLimit: BigInt, + utilizedCreditId: Bytes, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + durationOrDate: BigInt, + expiration: BigInt, + allowedAcceptor: Address, + proposerSpecHash: Bytes, + isOffer: boolean, + refinancingLoanId: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanContract: Address +): ElasticChainlinkProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) + ) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + + let proposalTuple = new ethereum.Tuple() + proposalTuple.push(ethereum.Value.fromI32(collateralCategory)) + proposalTuple.push(ethereum.Value.fromAddress(collateralAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralId)) + proposalTuple.push(ethereum.Value.fromBoolean(checkCollateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromBytes(collateralStateFingerprint)) + proposalTuple.push(ethereum.Value.fromAddress(creditAddress)) + + let feedDenominationsArray = new Array() + for (let i = 0; i < feedIntermediaryDenominations.length; i++) { + feedDenominationsArray.push(ethereum.Value.fromBytes(feedIntermediaryDenominations[i])) + } + proposalTuple.push(ethereum.Value.fromArray(feedDenominationsArray)) + + let feedFlagsArray = new Array() + for (let i = 0; i < feedInvertFlags.length; i++) { + feedFlagsArray.push(ethereum.Value.fromBoolean(feedInvertFlags[i])) + } + proposalTuple.push(ethereum.Value.fromArray(feedFlagsArray)) + + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(loanToValue)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(minCreditAmount)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(availableCreditLimit)) + proposalTuple.push(ethereum.Value.fromBytes(utilizedCreditId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + proposalTuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(durationOrDate)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + proposalTuple.push(ethereum.Value.fromAddress(allowedAcceptor)) + proposalTuple.push(ethereum.Value.fromAddress(proposer)) + proposalTuple.push(ethereum.Value.fromBytes(proposerSpecHash)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + proposalTuple.push(ethereum.Value.fromAddress(loanContract)) + + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposalTuple)) + ) + + event.address = loanContract + + return event +} + +export function createUniswapV3LPIndividualProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + collateralId: BigInt, + token0Denominator: Address, + creditAddress: Address, + feedIntermediaryDenominations: Bytes[], + feedInvertFlags: boolean[], + loanToValue: BigInt, + minCreditAmount: BigInt, + availableCreditLimit: BigInt, + utilizedCreditId: Bytes, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + durationOrDate: BigInt, + expiration: BigInt, + acceptorController: Address, + acceptorControllerData: Bytes, + proposerSpecHash: Bytes, + isOffer: boolean, + refinancingLoanId: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanContract: Address +): UniswapV3LPIndividualProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) + ) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + + let proposalTuple = new ethereum.Tuple() + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralId)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromAddress(token0Denominator)) + + let feedDenominationsArray = new Array() + for (let i = 0; i < feedIntermediaryDenominations.length; i++) { + feedDenominationsArray.push(ethereum.Value.fromBytes(feedIntermediaryDenominations[i])) + } + proposalTuple.push(ethereum.Value.fromArray(feedDenominationsArray)) + + let feedFlagsArray = new Array() + for (let i = 0; i < feedInvertFlags.length; i++) { + feedFlagsArray.push(ethereum.Value.fromBoolean(feedInvertFlags[i])) + } + proposalTuple.push(ethereum.Value.fromArray(feedFlagsArray)) + + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(loanToValue)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(minCreditAmount)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(availableCreditLimit)) + proposalTuple.push(ethereum.Value.fromBytes(utilizedCreditId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + proposalTuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(durationOrDate)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + proposalTuple.push(ethereum.Value.fromAddress(acceptorController)) + proposalTuple.push(ethereum.Value.fromBytes(acceptorControllerData)) + proposalTuple.push(ethereum.Value.fromAddress(proposer)) + proposalTuple.push(ethereum.Value.fromBytes(proposerSpecHash)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + proposalTuple.push(ethereum.Value.fromAddress(loanContract)) + + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposalTuple)) + ) + + event.address = loanContract + + return event +} + +export function createUniswapV3LPSetProposalMadeEvent( + proposalHash: Bytes, + proposer: Address, + tokenAAllowlist: Bytes[], + tokenBAllowlist: Bytes[], + creditAddress: Address, + feedIntermediaryDenominations: Bytes[], + feedInvertFlags: boolean[], + loanToValue: BigInt, + minCreditAmount: BigInt, + availableCreditLimit: BigInt, + utilizedCreditId: Bytes, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + durationOrDate: BigInt, + expiration: BigInt, + acceptorController: Address, + acceptorControllerData: Bytes, + proposerSpecHash: Bytes, + isOffer: boolean, + refinancingLoanId: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanContract: Address +): UniswapV3LPSetProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) + ) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) + ) + + let proposalTuple = new ethereum.Tuple() + + let tokenAArray = new Array() + for (let i = 0; i < tokenAAllowlist.length; i++) { + tokenAArray.push(ethereum.Value.fromBytes(tokenAAllowlist[i])) + } + proposalTuple.push(ethereum.Value.fromArray(tokenAArray)) + + let tokenBArray = new Array() + for (let i = 0; i < tokenBAllowlist.length; i++) { + tokenBArray.push(ethereum.Value.fromBytes(tokenBAllowlist[i])) + } + proposalTuple.push(ethereum.Value.fromArray(tokenBArray)) + + proposalTuple.push(ethereum.Value.fromAddress(creditAddress)) + + let feedDenominationsArray = new Array() + for (let i = 0; i < feedIntermediaryDenominations.length; i++) { + feedDenominationsArray.push(ethereum.Value.fromBytes(feedIntermediaryDenominations[i])) + } + proposalTuple.push(ethereum.Value.fromArray(feedDenominationsArray)) + + let feedFlagsArray = new Array() + for (let i = 0; i < feedInvertFlags.length; i++) { + feedFlagsArray.push(ethereum.Value.fromBoolean(feedInvertFlags[i])) + } + proposalTuple.push(ethereum.Value.fromArray(feedFlagsArray)) + + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(loanToValue)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(minCreditAmount)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(availableCreditLimit)) + proposalTuple.push(ethereum.Value.fromBytes(utilizedCreditId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + proposalTuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(durationOrDate)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + proposalTuple.push(ethereum.Value.fromAddress(acceptorController)) + proposalTuple.push(ethereum.Value.fromBytes(acceptorControllerData)) + proposalTuple.push(ethereum.Value.fromAddress(proposer)) + proposalTuple.push(ethereum.Value.fromBytes(proposerSpecHash)) + proposalTuple.push(ethereum.Value.fromBoolean(isOffer)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + proposalTuple.push(ethereum.Value.fromAddress(loanContract)) + + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposalTuple)) + ) + + event.address = loanContract + + return event +} \ No newline at end of file diff --git a/packages/subgraph/tests/proposal.test.ts b/packages/subgraph/tests/proposal.test.ts new file mode 100644 index 00000000..02782483 --- /dev/null +++ b/packages/subgraph/tests/proposal.test.ts @@ -0,0 +1,431 @@ +import { assert, describe, test, clearStore, beforeEach, afterEach } from "matchstick-as/assembly/index" +import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts" +import { handleProposalMade as handleSimpleProposalMade } from "../src/simple-loan-simple-proposal" +import { handleProposalMade as handleListProposalMade } from "../src/simple-loan-list-proposal" +import { handleProposalMade as handleElasticProposalMade } from "../src/simple-loan-elastic-proposal" +import { handleProposalMade as handleElasticChainlinkProposalMade } from "../src/simple-loan-elastic-chainlink-proposal" +import { handleProposalMade as handleUniswapV3LPIndividualProposalMade } from "../src/simple-loan-uniswap-v-3-lp-individual-proposal" +import { handleProposalMade as handleUniswapV3LPSetProposalMade } from "../src/simple-loan-uniswap-v-3-lp-set-proposal" +import { createSimpleProposalMadeEvent, createListProposalMadeEvent, createElasticProposalMadeEvent, createElasticChainlinkProposalMadeEvent, createUniswapV3LPIndividualProposalMadeEvent, createUniswapV3LPSetProposalMadeEvent } from "./proposal-utils" + +describe("Proposal Events", () => { + beforeEach(() => { + clearStore() + }) + + afterEach(() => { + clearStore() + }) + + test("handleSimpleProposalMade - creates a new Proposal entity", () => { + const proposalHash = Bytes.fromHexString("0x1234") + const proposer = Address.fromString("0x0000000000000000000000000000000000000001") + const collateralCategory = 1 + const collateralAddress = Address.fromString("0x0000000000000000000000000000000000000002") + const collateralId = BigInt.fromI32(1) + const collateralAmount = BigInt.fromI32(100) + const checkCollateralStateFingerprint = true + const collateralStateFingerprint = Bytes.fromHexString("0x5678") + const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") + const creditAmount = BigInt.fromI32(1000) + const availableCreditLimit = BigInt.fromI32(2000) + const utilizedCreditId = Bytes.fromHexString("0x9abc") + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const durationOrDate = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567890) + const allowedAcceptor = Address.fromString("0x0000000000000000000000000000000000000004") + const proposerSpecHash = Bytes.fromHexString("0xdef0") + const isOffer = true + const refinancingLoanId = BigInt.fromI32(0) + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + const loanContract = Address.fromString("0x0000000000000000000000000000000000000005") + + const event = createSimpleProposalMadeEvent( + proposalHash, + proposer, + collateralCategory, + collateralAddress, + collateralId, + collateralAmount, + checkCollateralStateFingerprint, + collateralStateFingerprint, + creditAddress, + creditAmount, + availableCreditLimit, + utilizedCreditId, + fixedInterestAmount, + accruingInterestAPR, + durationOrDate, + expiration, + allowedAcceptor, + proposerSpecHash, + isOffer, + refinancingLoanId, + nonceSpace, + nonce, + loanContract + ) + + handleSimpleProposalMade(event) + + // Verify the Proposal entity was created + assert.entityCount("Proposal", 1) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposalType", "Simple") + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "collateralAmount", collateralAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "creditAmount", creditAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "status", "Active") + + // Verify the SimpleLoanSimpleProposalMade entity was created + assert.entityCount("SimpleLoanSimpleProposalMade", 1) + const eventId = event.transaction.hash.concatI32(event.logIndex.toI32()) + assert.fieldEquals("SimpleLoanSimpleProposalMade", eventId.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("SimpleLoanSimpleProposalMade", eventId.toHexString(), "proposer", proposer.toHexString()) + }) + + test("handleListProposalMade - creates a new Proposal entity", () => { + const proposalHash = Bytes.fromHexString("0x1234") + const proposer = Address.fromString("0x0000000000000000000000000000000000000001") + const collateralCategory = 1 + const collateralAddress = Address.fromString("0x0000000000000000000000000000000000000002") + const collateralIdsWhitelistMerkleRoot = Bytes.fromHexString("0x5678") + const collateralAmount = BigInt.fromI32(100) + const checkCollateralStateFingerprint = true + const collateralStateFingerprint = Bytes.fromHexString("0x9abc") + const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") + const creditAmount = BigInt.fromI32(1000) + const availableCreditLimit = BigInt.fromI32(2000) + const utilizedCreditId = Bytes.fromHexString("0xdef0") + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const durationOrDate = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567890) + const allowedAcceptor = Address.fromString("0x0000000000000000000000000000000000000004") + const proposerSpecHash = Bytes.fromHexString("0x1234") + const isOffer = true + const refinancingLoanId = BigInt.fromI32(0) + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + const loanContract = Address.fromString("0x0000000000000000000000000000000000000005") + + const event = createListProposalMadeEvent( + proposalHash, + proposer, + collateralCategory, + collateralAddress, + collateralIdsWhitelistMerkleRoot, + collateralAmount, + checkCollateralStateFingerprint, + collateralStateFingerprint, + creditAddress, + creditAmount, + availableCreditLimit, + utilizedCreditId, + fixedInterestAmount, + accruingInterestAPR, + durationOrDate, + expiration, + allowedAcceptor, + proposerSpecHash, + isOffer, + refinancingLoanId, + nonceSpace, + nonce, + loanContract + ) + + handleListProposalMade(event) + + // Verify the Proposal entity was created + assert.entityCount("Proposal", 1) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposalType", "List") + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "collateralAmount", collateralAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "creditAmount", creditAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "status", "Active") + + // Verify the SimpleLoanListProposalProposalMade entity was created + assert.entityCount("SimpleLoanListProposalProposalMade", 1) + const eventId = event.transaction.hash.concatI32(event.logIndex.toI32()) + assert.fieldEquals("SimpleLoanListProposalProposalMade", eventId.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("SimpleLoanListProposalProposalMade", eventId.toHexString(), "proposer", proposer.toHexString()) + }) + + test("handleElasticProposalMade - creates a new Proposal entity", () => { + const proposalHash = Bytes.fromHexString("0x1234") + const proposer = Address.fromString("0x0000000000000000000000000000000000000001") + const collateralCategory = 1 + const collateralAddress = Address.fromString("0x0000000000000000000000000000000000000002") + const collateralId = BigInt.fromI32(1) + const checkCollateralStateFingerprint = true + const collateralStateFingerprint = Bytes.fromHexString("0x5678") + const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") + const creditPerCollateralUnit = BigInt.fromI32(10) + const minCreditAmount = BigInt.fromI32(100) + const availableCreditLimit = BigInt.fromI32(2000) + const utilizedCreditId = Bytes.fromHexString("0x9abc") + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const durationOrDate = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567890) + const allowedAcceptor = Address.fromString("0x0000000000000000000000000000000000000004") + const proposerSpecHash = Bytes.fromHexString("0xdef0") + const isOffer = true + const refinancingLoanId = BigInt.fromI32(0) + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + const loanContract = Address.fromString("0x0000000000000000000000000000000000000005") + + const event = createElasticProposalMadeEvent( + proposalHash, + proposer, + collateralCategory, + collateralAddress, + collateralId, + checkCollateralStateFingerprint, + collateralStateFingerprint, + creditAddress, + creditPerCollateralUnit, + minCreditAmount, + availableCreditLimit, + utilizedCreditId, + fixedInterestAmount, + accruingInterestAPR, + durationOrDate, + expiration, + allowedAcceptor, + proposerSpecHash, + isOffer, + refinancingLoanId, + nonceSpace, + nonce, + loanContract + ) + + handleElasticProposalMade(event) + + // Verify the Proposal entity was created + assert.entityCount("Proposal", 1) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposalType", "Elastic") + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "creditPerCollateralUnit", creditPerCollateralUnit.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "minCreditAmount", minCreditAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "status", "Active") + + // Verify the SimpleLoanElasticProposalProposalMade entity was created + assert.entityCount("SimpleLoanElasticProposalProposalMade", 1) + const eventId = event.transaction.hash.concatI32(event.logIndex.toI32()) + assert.fieldEquals("SimpleLoanElasticProposalProposalMade", eventId.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("SimpleLoanElasticProposalProposalMade", eventId.toHexString(), "proposer", proposer.toHexString()) + }) + + test("handleElasticChainlinkProposalMade - creates a new Proposal entity", () => { + const proposalHash = Bytes.fromHexString("0x1234") + const proposer = Address.fromString("0x0000000000000000000000000000000000000001") + const collateralCategory = 1 + const collateralAddress = Address.fromString("0x0000000000000000000000000000000000000002") + const collateralId = BigInt.fromI32(1) + const checkCollateralStateFingerprint = true + const collateralStateFingerprint = Bytes.fromHexString("0x5678") + const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") + const feedIntermediaryDenominations = [Bytes.fromHexString("0x9abc")] + const feedInvertFlags = [true] + const loanToValue = BigInt.fromI32(80) + const minCreditAmount = BigInt.fromI32(100) + const availableCreditLimit = BigInt.fromI32(2000) + const utilizedCreditId = Bytes.fromHexString("0xdef0") + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const durationOrDate = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567890) + const allowedAcceptor = Address.fromString("0x0000000000000000000000000000000000000004") + const proposerSpecHash = Bytes.fromHexString("0x1234") + const isOffer = true + const refinancingLoanId = BigInt.fromI32(0) + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + const loanContract = Address.fromString("0x0000000000000000000000000000000000000005") + + const event = createElasticChainlinkProposalMadeEvent( + proposalHash, + proposer, + collateralCategory, + collateralAddress, + collateralId, + checkCollateralStateFingerprint, + collateralStateFingerprint, + creditAddress, + feedIntermediaryDenominations, + feedInvertFlags, + loanToValue, + minCreditAmount, + availableCreditLimit, + utilizedCreditId, + fixedInterestAmount, + accruingInterestAPR, + durationOrDate, + expiration, + allowedAcceptor, + proposerSpecHash, + isOffer, + refinancingLoanId, + nonceSpace, + nonce, + loanContract + ) + + handleElasticChainlinkProposalMade(event) + + // Verify the Proposal entity was created + assert.entityCount("Proposal", 1) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposalType", "ElasticChainlink") + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "loanToValue", loanToValue.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "minCreditAmount", minCreditAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "status", "Active") + + // Verify the SimpleLoanElasticChainlinkProposalProposalMade entity was created + assert.entityCount("SimpleLoanElasticChainlinkProposalProposalMade", 1) + const eventId = event.transaction.hash.concatI32(event.logIndex.toI32()) + assert.fieldEquals("SimpleLoanElasticChainlinkProposalProposalMade", eventId.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("SimpleLoanElasticChainlinkProposalProposalMade", eventId.toHexString(), "proposer", proposer.toHexString()) + }) + + test("handleUniswapV3LPIndividualProposalMade - creates a new Proposal entity", () => { + const proposalHash = Bytes.fromHexString("0x1234") + const proposer = Address.fromString("0x0000000000000000000000000000000000000001") + const collateralId = BigInt.fromI32(1) + const token0Denominator = Address.fromString("0x0000000000000000000000000000000000000002") + const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") + const feedIntermediaryDenominations = [Bytes.fromHexString("0x5678")] + const feedInvertFlags = [true] + const loanToValue = BigInt.fromI32(80) + const minCreditAmount = BigInt.fromI32(100) + const availableCreditLimit = BigInt.fromI32(2000) + const utilizedCreditId = Bytes.fromHexString("0x9abc") + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const durationOrDate = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567890) + const acceptorController = Address.fromString("0x0000000000000000000000000000000000000004") + const acceptorControllerData = Bytes.fromHexString("0xdef0") + const proposerSpecHash = Bytes.fromHexString("0x1234") + const isOffer = true + const refinancingLoanId = BigInt.fromI32(0) + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + const loanContract = Address.fromString("0x0000000000000000000000000000000000000005") + + const event = createUniswapV3LPIndividualProposalMadeEvent( + proposalHash, + proposer, + collateralId, + token0Denominator, + creditAddress, + feedIntermediaryDenominations, + feedInvertFlags, + loanToValue, + minCreditAmount, + availableCreditLimit, + utilizedCreditId, + fixedInterestAmount, + accruingInterestAPR, + durationOrDate, + expiration, + acceptorController, + acceptorControllerData, + proposerSpecHash, + isOffer, + refinancingLoanId, + nonceSpace, + nonce, + loanContract + ) + + handleUniswapV3LPIndividualProposalMade(event) + + // Verify the Proposal entity was created + assert.entityCount("Proposal", 1) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposalType", "UniswapV3LPIndividual") + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "loanToValue", loanToValue.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "minCreditAmount", minCreditAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "status", "Active") + + // Verify the SimpleLoanUniswapV3LPIndividualProposalProposalMade entity was created + assert.entityCount("SimpleLoanUniswapV3LPIndividualProposalProposalMade", 1) + const eventId = event.transaction.hash.concatI32(event.logIndex.toI32()) + assert.fieldEquals("SimpleLoanUniswapV3LPIndividualProposalProposalMade", eventId.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("SimpleLoanUniswapV3LPIndividualProposalProposalMade", eventId.toHexString(), "proposer", proposer.toHexString()) + }) + + test("handleUniswapV3LPSetProposalMade - creates a new Proposal entity", () => { + const proposalHash = Bytes.fromHexString("0x1234") + const proposer = Address.fromString("0x0000000000000000000000000000000000000001") + const tokenAAllowlist = [Bytes.fromHexString("0x5678")] + const tokenBAllowlist = [Bytes.fromHexString("0x9abc")] + const creditAddress = Address.fromString("0x0000000000000000000000000000000000000002") + const feedIntermediaryDenominations = [Bytes.fromHexString("0xdef0")] + const feedInvertFlags = [true] + const loanToValue = BigInt.fromI32(80) + const minCreditAmount = BigInt.fromI32(100) + const availableCreditLimit = BigInt.fromI32(2000) + const utilizedCreditId = Bytes.fromHexString("0x1234") + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const durationOrDate = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567890) + const acceptorController = Address.fromString("0x0000000000000000000000000000000000000003") + const acceptorControllerData = Bytes.fromHexString("0x5678") + const proposerSpecHash = Bytes.fromHexString("0x9abc") + const isOffer = true + const refinancingLoanId = BigInt.fromI32(0) + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + const loanContract = Address.fromString("0x0000000000000000000000000000000000000004") + + const event = createUniswapV3LPSetProposalMadeEvent( + proposalHash, + proposer, + tokenAAllowlist, + tokenBAllowlist, + creditAddress, + feedIntermediaryDenominations, + feedInvertFlags, + loanToValue, + minCreditAmount, + availableCreditLimit, + utilizedCreditId, + fixedInterestAmount, + accruingInterestAPR, + durationOrDate, + expiration, + acceptorController, + acceptorControllerData, + proposerSpecHash, + isOffer, + refinancingLoanId, + nonceSpace, + nonce, + loanContract + ) + + handleUniswapV3LPSetProposalMade(event) + + // Verify the Proposal entity was created + assert.entityCount("Proposal", 1) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposalType", "UniswapV3LPSet") + assert.fieldEquals("Proposal", proposalHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "loanToValue", loanToValue.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "minCreditAmount", minCreditAmount.toString()) + assert.fieldEquals("Proposal", proposalHash.toHexString(), "status", "Active") + + // Verify the SimpleLoanUniswapV3LPSetProposalProposalMade entity was created + assert.entityCount("SimpleLoanUniswapV3LPSetProposalProposalMade", 1) + const eventId = event.transaction.hash.concatI32(event.logIndex.toI32()) + assert.fieldEquals("SimpleLoanUniswapV3LPSetProposalProposalMade", eventId.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("SimpleLoanUniswapV3LPSetProposalProposalMade", eventId.toHexString(), "proposer", proposer.toHexString()) + }) +}) \ No newline at end of file diff --git a/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts b/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts deleted file mode 100644 index 249dd824..00000000 --- a/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" - -export function createProposalMadeEvent( - proposalHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ProposalMade { - let proposalMadeEvent = changetype(newMockEvent()) - - proposalMadeEvent.parameters = new Array() - - proposalMadeEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return proposalMadeEvent -} diff --git a/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts b/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts deleted file mode 100644 index cb88bb0b..00000000 --- a/packages/subgraph/tests/simple-loan-elastic-chainlink-proposal.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/schema" -import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticChainlinkProposal/SimpleLoanElasticChainlinkProposal" -import { handleProposalMade } from "../src/simple-loan-elastic-chainlink-proposal" -import { createProposalMadeEvent } from "./simple-loan-elastic-chainlink-proposal-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let proposalHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let proposal = "ethereum.Tuple Not implemented" - let newProposalMadeEvent = createProposalMadeEvent( - proposalHash, - proposer, - proposal - ) - handleProposalMade(newProposalMadeEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("ProposalMade created and stored", () => { - assert.entityCount("ProposalMade", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposalHash", - "1234567890" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts b/packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts deleted file mode 100644 index 490f1cd3..00000000 --- a/packages/subgraph/tests/simple-loan-elastic-proposal-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" - -export function createProposalMadeEvent( - proposalHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ProposalMade { - let proposalMadeEvent = changetype(newMockEvent()) - - proposalMadeEvent.parameters = new Array() - - proposalMadeEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return proposalMadeEvent -} diff --git a/packages/subgraph/tests/simple-loan-elastic-proposal.test.ts b/packages/subgraph/tests/simple-loan-elastic-proposal.test.ts deleted file mode 100644 index f872f535..00000000 --- a/packages/subgraph/tests/simple-loan-elastic-proposal.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/schema" -import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasticProposal/SimpleLoanElasticProposal" -import { handleProposalMade } from "../src/simple-loan-elastic-proposal" -import { createProposalMadeEvent } from "./simple-loan-elastic-proposal-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let proposalHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let proposal = "ethereum.Tuple Not implemented" - let newProposalMadeEvent = createProposalMadeEvent( - proposalHash, - proposer, - proposal - ) - handleProposalMade(newProposalMadeEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("ProposalMade created and stored", () => { - assert.entityCount("ProposalMade", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposalHash", - "1234567890" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/simple-loan-list-proposal-utils.ts b/packages/subgraph/tests/simple-loan-list-proposal-utils.ts deleted file mode 100644 index 94b71dde..00000000 --- a/packages/subgraph/tests/simple-loan-list-proposal-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" - -export function createProposalMadeEvent( - proposalHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ProposalMade { - let proposalMadeEvent = changetype(newMockEvent()) - - proposalMadeEvent.parameters = new Array() - - proposalMadeEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return proposalMadeEvent -} diff --git a/packages/subgraph/tests/simple-loan-list-proposal.test.ts b/packages/subgraph/tests/simple-loan-list-proposal.test.ts deleted file mode 100644 index 853d7cfc..00000000 --- a/packages/subgraph/tests/simple-loan-list-proposal.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/schema" -import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanListProposal/SimpleLoanListProposal" -import { handleProposalMade } from "../src/simple-loan-list-proposal" -import { createProposalMadeEvent } from "./simple-loan-list-proposal-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let proposalHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let proposal = "ethereum.Tuple Not implemented" - let newProposalMadeEvent = createProposalMadeEvent( - proposalHash, - proposer, - proposal - ) - handleProposalMade(newProposalMadeEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("ProposalMade created and stored", () => { - assert.entityCount("ProposalMade", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposalHash", - "1234567890" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/simple-loan-simple-proposal-utils.ts b/packages/subgraph/tests/simple-loan-simple-proposal-utils.ts deleted file mode 100644 index 0b321ca2..00000000 --- a/packages/subgraph/tests/simple-loan-simple-proposal-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" - -export function createProposalMadeEvent( - proposalHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ProposalMade { - let proposalMadeEvent = changetype(newMockEvent()) - - proposalMadeEvent.parameters = new Array() - - proposalMadeEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return proposalMadeEvent -} diff --git a/packages/subgraph/tests/simple-loan-simple-proposal.test.ts b/packages/subgraph/tests/simple-loan-simple-proposal.test.ts deleted file mode 100644 index 0483d561..00000000 --- a/packages/subgraph/tests/simple-loan-simple-proposal.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/schema" -import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanSimpleProposal/SimpleLoanSimpleProposal" -import { handleProposalMade } from "../src/simple-loan-simple-proposal" -import { createProposalMadeEvent } from "./simple-loan-simple-proposal-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let proposalHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let proposal = "ethereum.Tuple Not implemented" - let newProposalMadeEvent = createProposalMadeEvent( - proposalHash, - proposer, - proposal - ) - handleProposalMade(newProposalMadeEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("ProposalMade created and stored", () => { - assert.entityCount("ProposalMade", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposalHash", - "1234567890" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts deleted file mode 100644 index d1ad3e5f..00000000 --- a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/SimpleLoanUniswapV3LPIndividualProposal/SimpleLoanUniswapV3LPIndividualProposal" - -export function createProposalMadeEvent( - proposalHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ProposalMade { - let proposalMadeEvent = changetype(newMockEvent()) - - proposalMadeEvent.parameters = new Array() - - proposalMadeEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return proposalMadeEvent -} diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts deleted file mode 100644 index f64cce11..00000000 --- a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-individual-proposal.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/schema" -import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanUniswapV3LPIndividualProposal/SimpleLoanUniswapV3LPIndividualProposal" -import { handleProposalMade } from "../src/simple-loan-uniswap-v-3-lp-individual-proposal" -import { createProposalMadeEvent } from "./simple-loan-uniswap-v-3-lp-individual-proposal-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let proposalHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let proposal = "ethereum.Tuple Not implemented" - let newProposalMadeEvent = createProposalMadeEvent( - proposalHash, - proposer, - proposal - ) - handleProposalMade(newProposalMadeEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("ProposalMade created and stored", () => { - assert.entityCount("ProposalMade", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposalHash", - "1234567890" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts deleted file mode 100644 index e5036e4b..00000000 --- a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/SimpleLoanUniswapV3LPSetProposal/SimpleLoanUniswapV3LPSetProposal" - -export function createProposalMadeEvent( - proposalHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ProposalMade { - let proposalMadeEvent = changetype(newMockEvent()) - - proposalMadeEvent.parameters = new Array() - - proposalMadeEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - proposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return proposalMadeEvent -} diff --git a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts b/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts deleted file mode 100644 index c5d587a5..00000000 --- a/packages/subgraph/tests/simple-loan-uniswap-v-3-lp-set-proposal.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address } from "@graphprotocol/graph-ts" -import { ProposalMade } from "../generated/schema" -import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanUniswapV3LPSetProposal/SimpleLoanUniswapV3LPSetProposal" -import { handleProposalMade } from "../src/simple-loan-uniswap-v-3-lp-set-proposal" -import { createProposalMadeEvent } from "./simple-loan-uniswap-v-3-lp-set-proposal-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let proposalHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" - ) - let proposal = "ethereum.Tuple Not implemented" - let newProposalMadeEvent = createProposalMadeEvent( - proposalHash, - proposer, - proposal - ) - handleProposalMade(newProposalMadeEvent) - }) - - afterAll(() => { - clearStore() - }) - - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test - - test("ProposalMade created and stored", () => { - assert.entityCount("ProposalMade", 1) - - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposalHash", - "1234567890" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" - ) - assert.fieldEquals( - "ProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" - ) - - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts - }) -}) diff --git a/packages/subgraph/tests/simple-loan-utils.ts b/packages/subgraph/tests/simple-loan-utils.ts index a2b1e216..de997614 100644 --- a/packages/subgraph/tests/simple-loan-utils.ts +++ b/packages/subgraph/tests/simple-loan-utils.ts @@ -1,60 +1,67 @@ -import { newMockEvent } from "matchstick-as" -import { ethereum, Bytes, Address, BigInt } from "@graphprotocol/graph-ts" -import { - ExtensionProposalMade, - LOANClaimed, - LOANCreated, - LOANExtended, - LOANPaidBack, - PoolSupply, - PoolWithdraw, - VaultPull, - VaultPush, - VaultPushFrom -} from "../generated/SimpleLoan/SimpleLoan" - -export function createExtensionProposalMadeEvent( - extensionHash: Bytes, - proposer: Address, - proposal: ethereum.Tuple -): ExtensionProposalMade { - let extensionProposalMadeEvent = - changetype(newMockEvent()) - - extensionProposalMadeEvent.parameters = new Array() - - extensionProposalMadeEvent.parameters.push( - new ethereum.EventParam( - "extensionHash", - ethereum.Value.fromFixedBytes(extensionHash) - ) - ) - extensionProposalMadeEvent.parameters.push( - new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) - ) - extensionProposalMadeEvent.parameters.push( - new ethereum.EventParam("proposal", ethereum.Value.fromTuple(proposal)) - ) - - return extensionProposalMadeEvent +import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" +import { LOANCreated, LOANPaidBack, LOANClaimed, LOANExtended, ExtensionProposalMade } from "../generated/SimpleLoan/SimpleLoan" +import { assert, test, newMockEvent, dataSourceMock } from 'matchstick-as/assembly/index' +import { handleLOANCreated } from "../src/simple-loan" +import { Loan } from "../generated/schema"; + +// Define a class to hold the parameters +export class TestLoanParams { + proposalHash: Bytes = Bytes.fromHexString("0x1234"); + proposalContract: Address = Address.fromString("0x0000000000000000000000000000000000000001"); + refinancingLoanId: BigInt = BigInt.fromI32(0); + lender: Address = Address.fromString("0x0000000000000000000000000000000000000002"); + borrower: Address = Address.fromString("0x0000000000000000000000000000000000000003"); + duration: BigInt = BigInt.fromI32(30); + createdAt: BigInt = BigInt.fromI32(1234567890); + collateralAssetAddress: Address = Address.fromString("0x0000000000000000000000000000000000000004"); + collateralId: BigInt = BigInt.fromI32(1); + collateralCategory: i32 = 1; + collateralAmount: BigInt = BigInt.fromI32(100); + creditAssetAddress: Address = Address.fromString("0x0000000000000000000000000000000000000005"); + creditId: BigInt = BigInt.fromI32(0); + creditCategory: i32 = 0; + creditAmount: BigInt = BigInt.fromI32(1000); + fixedInterestAmount: BigInt = BigInt.fromI32(50); + accruingInterestAPR: i32 = 1000; + lenderSpecHash: Bytes = Bytes.fromHexString("0x5678"); + borrowerSpecHash: Bytes = Bytes.fromHexString("0x9abc"); + sourceOfFunds: Address = Address.fromString("0x0000000000000000000000000000000000000003"); + extra: Bytes = Bytes.fromHexString("0x1234"); + loanTokenAddress: Address = Address.fromString("0x0000000000000000000000000000000000000006"); } -export function createLOANClaimedEvent( - loanId: BigInt, - defaulted: boolean -): LOANClaimed { - let loanClaimedEvent = changetype(newMockEvent()) - - loanClaimedEvent.parameters = new Array() - - loanClaimedEvent.parameters.push( - new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) - ) - loanClaimedEvent.parameters.push( - new ethereum.EventParam("defaulted", ethereum.Value.fromBoolean(defaulted)) - ) - - return loanClaimedEvent +export function createDefaultTestLoan(loanId: BigInt, params: TestLoanParams | null = null): Loan { + // Use default params if none provided + const p = params ? params : new TestLoanParams(); + + const createEvent = createLOANCreatedEvent( + loanId, + p.proposalHash, + p.proposalContract, + p.refinancingLoanId, + p.lender, + p.borrower, + p.duration, + p.createdAt, + p.collateralAssetAddress, + p.collateralId, + p.collateralCategory, + p.collateralAmount, + p.creditAssetAddress, + p.creditId, + p.creditCategory, + p.creditAmount, + p.fixedInterestAmount, + p.accruingInterestAPR, + p.lenderSpecHash, + p.borrowerSpecHash, + p.sourceOfFunds, + p.extra, + p.loanTokenAddress + ); + + const loan = handleLOANCreated(createEvent); + return loan; } export function createLOANCreatedEvent( @@ -62,206 +69,269 @@ export function createLOANCreatedEvent( proposalHash: Bytes, proposalContract: Address, refinancingLoanId: BigInt, - terms: ethereum.Tuple, - lenderSpec: ethereum.Tuple, - extra: Bytes + lender: Address, + borrower: Address, + duration: BigInt, + createdAt: BigInt, + collateralAssetAddress: Address, + collateralId: BigInt, + collateralCategory: i32, + collateralAmount: BigInt, + creditAssetAddress: Address, + creditId: BigInt, + creditCategory: i32, + creditAmount: BigInt, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + lenderSpecHash: Bytes, + borrowerSpecHash: Bytes, + sourceOfFunds: Address, + extra: Bytes, + loanTokenAddress: Address ): LOANCreated { - let loanCreatedEvent = changetype(newMockEvent()) - - loanCreatedEvent.parameters = new Array() - - loanCreatedEvent.parameters.push( + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) ) - loanCreatedEvent.parameters.push( - new ethereum.EventParam( - "proposalHash", - ethereum.Value.fromFixedBytes(proposalHash) - ) + event.parameters.push( + new ethereum.EventParam("proposalHash", ethereum.Value.fromBytes(proposalHash)) ) - loanCreatedEvent.parameters.push( - new ethereum.EventParam( - "proposalContract", - ethereum.Value.fromAddress(proposalContract) - ) + event.parameters.push( + new ethereum.EventParam("proposalContract", ethereum.Value.fromAddress(proposalContract)) ) - loanCreatedEvent.parameters.push( - new ethereum.EventParam( - "refinancingLoanId", - ethereum.Value.fromUnsignedBigInt(refinancingLoanId) - ) + event.parameters.push( + new ethereum.EventParam("refinancingLoanId", ethereum.Value.fromUnsignedBigInt(refinancingLoanId)) ) - loanCreatedEvent.parameters.push( - new ethereum.EventParam("terms", ethereum.Value.fromTuple(terms)) + event.parameters.push( + new ethereum.EventParam("terms", ethereum.Value.fromTuple(createTermsTuple( + lender, + borrower, + duration, + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount, + creditAssetAddress, + creditId, + creditCategory, + creditAmount, + fixedInterestAmount, + accruingInterestAPR, + lenderSpecHash, + borrowerSpecHash + ))) ) - loanCreatedEvent.parameters.push( - new ethereum.EventParam("lenderSpec", ethereum.Value.fromTuple(lenderSpec)) + event.parameters.push( + new ethereum.EventParam("lenderSpec", ethereum.Value.fromTuple(createLenderSpecTuple( + sourceOfFunds + ))) ) - loanCreatedEvent.parameters.push( + event.parameters.push( new ethereum.EventParam("extra", ethereum.Value.fromBytes(extra)) ) - return loanCreatedEvent -} - -export function createLOANExtendedEvent( - loanId: BigInt, - originalDefaultTimestamp: BigInt, - extendedDefaultTimestamp: BigInt -): LOANExtended { - let loanExtendedEvent = changetype(newMockEvent()) - - loanExtendedEvent.parameters = new Array() + // TODO is this fine or we should also pass the loan contract address and set it here? + // event.address = loanContractAddress - loanExtendedEvent.parameters.push( - new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) - ) - loanExtendedEvent.parameters.push( - new ethereum.EventParam( - "originalDefaultTimestamp", - ethereum.Value.fromUnsignedBigInt(originalDefaultTimestamp) - ) - ) - loanExtendedEvent.parameters.push( - new ethereum.EventParam( - "extendedDefaultTimestamp", - ethereum.Value.fromUnsignedBigInt(extendedDefaultTimestamp) - ) - ) + return event +} - return loanExtendedEvent +function createTermsTuple( + lender: Address, + borrower: Address, + duration: BigInt, + collateralAssetAddress: Address, + collateralId: BigInt, + collateralCategory: i32, + collateralAmount: BigInt, + creditAssetAddress: Address, + creditId: BigInt, + creditCategory: i32, + creditAmount: BigInt, + fixedInterestAmount: BigInt, + accruingInterestAPR: i32, + lenderSpecHash: Bytes, + borrowerSpecHash: Bytes +): ethereum.Tuple { + let tuple = new ethereum.Tuple() + tuple.push(ethereum.Value.fromAddress(lender)) + tuple.push(ethereum.Value.fromAddress(borrower)) + tuple.push(ethereum.Value.fromUnsignedBigInt(duration)) + tuple.push(ethereum.Value.fromTuple(createAssetTuple( + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount + ))) + tuple.push(ethereum.Value.fromTuple(createAssetTuple( + creditAssetAddress, + creditId, + creditCategory, + creditAmount + ))) + tuple.push(ethereum.Value.fromUnsignedBigInt(fixedInterestAmount)) + tuple.push(ethereum.Value.fromI32(accruingInterestAPR)) + tuple.push(ethereum.Value.fromBytes(lenderSpecHash)) + tuple.push(ethereum.Value.fromBytes(borrowerSpecHash)) + return tuple } -export function createLOANPaidBackEvent(loanId: BigInt): LOANPaidBack { - let loanPaidBackEvent = changetype(newMockEvent()) +function createAssetTuple( + assetAddress: Address, + id: BigInt, + category: i32, + amount: BigInt +): ethereum.Tuple { + let tuple = new ethereum.Tuple() + tuple.push(ethereum.Value.fromI32(category)) + tuple.push(ethereum.Value.fromAddress(assetAddress)) + tuple.push(ethereum.Value.fromUnsignedBigInt(id)) + tuple.push(ethereum.Value.fromUnsignedBigInt(amount)) + return tuple +} - loanPaidBackEvent.parameters = new Array() +function createLenderSpecTuple( + sourceOfFunds: Address +): ethereum.Tuple { + let tuple = new ethereum.Tuple() + tuple.push(ethereum.Value.fromAddress(sourceOfFunds)) + return tuple +} - loanPaidBackEvent.parameters.push( +export function createLOANClaimedEvent( + loanId: BigInt, + defaulted: boolean, + loanTokenAddress: Address +): LOANClaimed { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) ) + event.parameters.push( + new ethereum.EventParam("defaulted", ethereum.Value.fromBoolean(defaulted)) + ) - return loanPaidBackEvent -} - -export function createPoolSupplyEvent( - asset: ethereum.Tuple, - poolAdapter: Address, - pool: Address, - owner: Address -): PoolSupply { - let poolSupplyEvent = changetype(newMockEvent()) + // Mock the loanToken() call + event.address = loanTokenAddress - poolSupplyEvent.parameters = new Array() + return event +} - poolSupplyEvent.parameters.push( - new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) - ) - poolSupplyEvent.parameters.push( - new ethereum.EventParam( - "poolAdapter", - ethereum.Value.fromAddress(poolAdapter) - ) +export function createLOANExtendedEvent( + loanId: BigInt, + originalDefaultTimestamp: BigInt, + extendedDefaultTimestamp: BigInt, + loanTokenAddress: Address +): LOANExtended { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) ) - poolSupplyEvent.parameters.push( - new ethereum.EventParam("pool", ethereum.Value.fromAddress(pool)) + event.parameters.push( + new ethereum.EventParam("originalDefaultTimestamp", ethereum.Value.fromUnsignedBigInt(originalDefaultTimestamp)) ) - poolSupplyEvent.parameters.push( - new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + event.parameters.push( + new ethereum.EventParam("extendedDefaultTimestamp", ethereum.Value.fromUnsignedBigInt(extendedDefaultTimestamp)) ) - return poolSupplyEvent -} - -export function createPoolWithdrawEvent( - asset: ethereum.Tuple, - poolAdapter: Address, - pool: Address, - owner: Address -): PoolWithdraw { - let poolWithdrawEvent = changetype(newMockEvent()) + // Mock the loanToken() call + event.address = loanTokenAddress - poolWithdrawEvent.parameters = new Array() + return event +} - poolWithdrawEvent.parameters.push( - new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) - ) - poolWithdrawEvent.parameters.push( - new ethereum.EventParam( - "poolAdapter", - ethereum.Value.fromAddress(poolAdapter) - ) +export function createExtensionProposalMadeEvent( + extensionHash: Bytes, + proposer: Address, + loanId: BigInt, + compensationAddress: Address, + compensationAmount: BigInt, + duration: BigInt, + expiration: BigInt, + nonceSpace: BigInt, + nonce: BigInt, + loanTokenAddress: Address +): ExtensionProposalMade { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("extensionHash", ethereum.Value.fromBytes(extensionHash)) ) - poolWithdrawEvent.parameters.push( - new ethereum.EventParam("pool", ethereum.Value.fromAddress(pool)) + event.parameters.push( + new ethereum.EventParam("proposer", ethereum.Value.fromAddress(proposer)) ) - poolWithdrawEvent.parameters.push( - new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner)) + event.parameters.push( + new ethereum.EventParam("proposal", ethereum.Value.fromTuple(createExtensionProposalTuple( + loanId, + compensationAddress, + compensationAmount, + duration, + expiration, + proposer, + nonceSpace, + nonce + ))) ) - return poolWithdrawEvent -} - -export function createVaultPullEvent( - asset: ethereum.Tuple, - origin: Address -): VaultPull { - let vaultPullEvent = changetype(newMockEvent()) + // Mock the loanToken() call + event.address = loanTokenAddress - vaultPullEvent.parameters = new Array() - - vaultPullEvent.parameters.push( - new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) - ) - vaultPullEvent.parameters.push( - new ethereum.EventParam("origin", ethereum.Value.fromAddress(origin)) - ) - - return vaultPullEvent + return event } -export function createVaultPushEvent( - asset: ethereum.Tuple, - beneficiary: Address -): VaultPush { - let vaultPushEvent = changetype(newMockEvent()) - - vaultPushEvent.parameters = new Array() - - vaultPushEvent.parameters.push( - new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) - ) - vaultPushEvent.parameters.push( - new ethereum.EventParam( - "beneficiary", - ethereum.Value.fromAddress(beneficiary) - ) - ) - - return vaultPushEvent +function createExtensionProposalTuple( + loanId: BigInt, + compensationAddress: Address, + compensationAmount: BigInt, + duration: BigInt, + expiration: BigInt, + proposer: Address, + nonceSpace: BigInt, + nonce: BigInt +): ethereum.Tuple { + let tuple = new ethereum.Tuple() + tuple.push(ethereum.Value.fromUnsignedBigInt(loanId)) + tuple.push(ethereum.Value.fromAddress(compensationAddress)) + tuple.push(ethereum.Value.fromUnsignedBigInt(compensationAmount)) + tuple.push(ethereum.Value.fromUnsignedBigInt(duration)) + tuple.push(ethereum.Value.fromUnsignedBigInt(expiration)) + tuple.push(ethereum.Value.fromAddress(proposer)) + tuple.push(ethereum.Value.fromUnsignedBigInt(nonceSpace)) + tuple.push(ethereum.Value.fromUnsignedBigInt(nonce)) + return tuple } -export function createVaultPushFromEvent( - asset: ethereum.Tuple, - origin: Address, - beneficiary: Address -): VaultPushFrom { - let vaultPushFromEvent = changetype(newMockEvent()) - - vaultPushFromEvent.parameters = new Array() - vaultPushFromEvent.parameters.push( - new ethereum.EventParam("asset", ethereum.Value.fromTuple(asset)) - ) - vaultPushFromEvent.parameters.push( - new ethereum.EventParam("origin", ethereum.Value.fromAddress(origin)) - ) - vaultPushFromEvent.parameters.push( - new ethereum.EventParam( - "beneficiary", - ethereum.Value.fromAddress(beneficiary) +export function createLOANPaidBackEvent( + loanId: BigInt, + paidBackAt: BigInt, + loanTokenAddress: Address + ): LOANPaidBack { + let event = changetype(newMockEvent()) + + event.parameters = new Array() + + event.parameters.push( + new ethereum.EventParam("loanId", ethereum.Value.fromUnsignedBigInt(loanId)) ) - ) - - return vaultPushFromEvent -} + event.parameters.push( + new ethereum.EventParam("paidBackAt", ethereum.Value.fromUnsignedBigInt(paidBackAt)) + ) + + // Mock the loanToken() call + event.address = loanTokenAddress + + return event + } + \ No newline at end of file diff --git a/packages/subgraph/tests/simple-loan.test.ts b/packages/subgraph/tests/simple-loan.test.ts index b132e0be..d744d8ba 100644 --- a/packages/subgraph/tests/simple-loan.test.ts +++ b/packages/subgraph/tests/simple-loan.test.ts @@ -1,66 +1,372 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll -} from "matchstick-as/assembly/index" -import { Bytes, Address, BigInt } from "@graphprotocol/graph-ts" -import { ExtensionProposalMade } from "../generated/schema" -import { ExtensionProposalMade as ExtensionProposalMadeEvent } from "../generated/SimpleLoan/SimpleLoan" -import { handleExtensionProposalMade } from "../src/simple-loan" -import { createExtensionProposalMadeEvent } from "./simple-loan-utils" - -// Tests structure (matchstick-as >=0.5.0) -// https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#tests-structure - -describe("Describe entity assertions", () => { - beforeAll(() => { - let extensionHash = Bytes.fromI32(1234567890) - let proposer = Address.fromString( - "0x0000000000000000000000000000000000000001" +import { assert, describe, test, clearStore, beforeEach, afterEach } from "matchstick-as/assembly/index" +import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts" +import { handleLOANCreated, handleLOANPaidBack, handleLOANClaimed, handleLOANExtended, handleExtensionProposalMade } from "../src/simple-loan" +import { createLOANCreatedEvent, createLOANPaidBackEvent, createLOANClaimedEvent, createLOANExtendedEvent, createExtensionProposalMadeEvent } from "./simple-loan-utils" + +describe("SimpleLoan", () => { + beforeEach(() => { + clearStore() + }) + + afterEach(() => { + clearStore() + }) + + test("handleLOANCreated - creates a new Loan entity", () => { + const loanId = BigInt.fromI32(1) + const proposalHash = Bytes.fromHexString("0x1234") + const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") + const refinancingLoanId = BigInt.fromI32(0) + const lender = Address.fromString("0x0000000000000000000000000000000000000002") + const borrower = Address.fromString("0x0000000000000000000000000000000000000003") + const duration = BigInt.fromI32(30) + const createdAt = BigInt.fromI32(1234567890) + const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") + const collateralId = BigInt.fromI32(1) + const collateralCategory = 1 + const collateralAmount = BigInt.fromI32(100) + const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") + const creditId = BigInt.fromI32(0) + const creditCategory = 0 + const creditAmount = BigInt.fromI32(1000) + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const lenderSpecHash = Bytes.fromHexString("0x5678") + const borrowerSpecHash = Bytes.fromHexString("0x9abc") + const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") + const extra = Bytes.fromHexString("0x1234") + const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + const event = createLOANCreatedEvent( + loanId, + proposalHash, + proposalContract, + refinancingLoanId, + lender, + borrower, + duration, + createdAt, + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount, + creditAssetAddress, + creditId, + creditCategory, + creditAmount, + fixedInterestAmount, + accruingInterestAPR, + lenderSpecHash, + borrowerSpecHash, + sourceOfFunds, + extra, + loanTokenAddress ) - let proposal = "ethereum.Tuple Not implemented" - let newExtensionProposalMadeEvent = createExtensionProposalMadeEvent( - extensionHash, - proposer, - proposal + + handleLOANCreated(event) + + const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) + assert.entityCount("Loan", 1) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "loanId", loanId.toString()) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "proposalHash", proposalHash.toHexString()) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "originalLender", lender.toHexString()) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "borrower", borrower.toHexString()) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "duration", duration.toString()) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "createdAt", createdAt.toString()) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "status", "Active") + }) + + test("handleLOANPaidBack - updates Loan status to Repaid", () => { + // First create a loan + const loanId = BigInt.fromI32(1) + const proposalHash = Bytes.fromHexString("0x1234") + const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") + const refinancingLoanId = BigInt.fromI32(0) + const lender = Address.fromString("0x0000000000000000000000000000000000000002") + const borrower = Address.fromString("0x0000000000000000000000000000000000000003") + const duration = BigInt.fromI32(30) + const createdAt = BigInt.fromI32(1234567890) + const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") + const collateralId = BigInt.fromI32(1) + const collateralCategory = 1 + const collateralAmount = BigInt.fromI32(100) + const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") + const creditId = BigInt.fromI32(0) + const creditCategory = 0 + const creditAmount = BigInt.fromI32(1000) + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const lenderSpecHash = Bytes.fromHexString("0x5678") + const borrowerSpecHash = Bytes.fromHexString("0x9abc") + const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") + const extra = Bytes.fromHexString("0x1234") + const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + const createEvent = createLOANCreatedEvent( + loanId, + proposalHash, + proposalContract, + refinancingLoanId, + lender, + borrower, + duration, + createdAt, + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount, + creditAssetAddress, + creditId, + creditCategory, + creditAmount, + fixedInterestAmount, + accruingInterestAPR, + lenderSpecHash, + borrowerSpecHash, + sourceOfFunds, + extra, + loanTokenAddress ) - handleExtensionProposalMade(newExtensionProposalMadeEvent) + + handleLOANCreated(createEvent) + + // Then pay it back + const paidBackAt = BigInt.fromI32(1234567891) + const payBackEvent = createLOANPaidBackEvent(loanId, paidBackAt, loanTokenAddress) + handleLOANPaidBack(payBackEvent) + + const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "status", "Repaid") + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "repaidAt", paidBackAt.toString()) }) - afterAll(() => { - clearStore() + test("handleLOANClaimed - updates Loan status to Claimed", () => { + // First create a loan + const loanId = BigInt.fromI32(1) + const proposalHash = Bytes.fromHexString("0x1234") + const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") + const refinancingLoanId = BigInt.fromI32(0) + const lender = Address.fromString("0x0000000000000000000000000000000000000002") + const borrower = Address.fromString("0x0000000000000000000000000000000000000003") + const duration = BigInt.fromI32(30) + const createdAt = BigInt.fromI32(1234567890) + const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") + const collateralId = BigInt.fromI32(1) + const collateralCategory = 1 + const collateralAmount = BigInt.fromI32(100) + const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") + const creditId = BigInt.fromI32(0) + const creditCategory = 0 + const creditAmount = BigInt.fromI32(1000) + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const lenderSpecHash = Bytes.fromHexString("0x5678") + const borrowerSpecHash = Bytes.fromHexString("0x9abc") + const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") + const extra = Bytes.fromHexString("0x1234") + const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + const createEvent = createLOANCreatedEvent( + loanId, + proposalHash, + proposalContract, + refinancingLoanId, + lender, + borrower, + duration, + createdAt, + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount, + creditAssetAddress, + creditId, + creditCategory, + creditAmount, + fixedInterestAmount, + accruingInterestAPR, + lenderSpecHash, + borrowerSpecHash, + sourceOfFunds, + extra, + loanTokenAddress + ) + + handleLOANCreated(createEvent) + + // Then claim it + const defaulted = true + const claimEvent = createLOANClaimedEvent(loanId, defaulted, loanTokenAddress) + handleLOANClaimed(claimEvent) + + const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "status", "Claimed") + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "hasDefaulted", defaulted.toString()) }) - // For more test scenarios, see: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#write-a-unit-test + test("handleLOANExtended - extends loan duration and updates default date", () => { + // First create a loan + const loanId = BigInt.fromI32(1) + const proposalHash = Bytes.fromHexString("0x1234") + const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") + const refinancingLoanId = BigInt.fromI32(0) + const lender = Address.fromString("0x0000000000000000000000000000000000000002") + const borrower = Address.fromString("0x0000000000000000000000000000000000000003") + const duration = BigInt.fromI32(30) + const createdAt = BigInt.fromI32(1234567890) + const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") + const collateralId = BigInt.fromI32(1) + const collateralCategory = 1 + const collateralAmount = BigInt.fromI32(100) + const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") + const creditId = BigInt.fromI32(0) + const creditCategory = 0 + const creditAmount = BigInt.fromI32(1000) + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const lenderSpecHash = Bytes.fromHexString("0x5678") + const borrowerSpecHash = Bytes.fromHexString("0x9abc") + const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") + const extra = Bytes.fromHexString("0x1234") + const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + const createEvent = createLOANCreatedEvent( + loanId, + proposalHash, + proposalContract, + refinancingLoanId, + lender, + borrower, + duration, + createdAt, + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount, + creditAssetAddress, + creditId, + creditCategory, + creditAmount, + fixedInterestAmount, + accruingInterestAPR, + lenderSpecHash, + borrowerSpecHash, + sourceOfFunds, + extra, + loanTokenAddress + ) - test("ExtensionProposalMade created and stored", () => { - assert.entityCount("ExtensionProposalMade", 1) + handleLOANCreated(createEvent) - // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function - assert.fieldEquals( - "ExtensionProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "extensionHash", - "1234567890" + // Then extend it + const originalDefaultTimestamp = BigInt.fromI32(1234567920) // 30 days after creation + const extendedDefaultTimestamp = BigInt.fromI32(1234567920 + 15) // 15 more days + const extendEvent = createLOANExtendedEvent( + loanId, + originalDefaultTimestamp, + extendedDefaultTimestamp, + loanTokenAddress ) - assert.fieldEquals( - "ExtensionProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposer", - "0x0000000000000000000000000000000000000001" + handleLOANExtended(extendEvent) + + const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "duration", "45") // 30 + 15 days + assert.fieldEquals("Loan", loanIdBytes.toHexString(), "defaultDate", extendedDefaultTimestamp.toString()) + + // Also verify the LOANExtended entity was created + const extendedEventId = extendEvent.transaction.hash.concatI32(extendEvent.logIndex.toI32()) + assert.entityCount("LOANExtended", 1) + assert.fieldEquals("LOANExtended", extendedEventId.toHexString(), "loanId", loanId.toString()) + assert.fieldEquals("LOANExtended", extendedEventId.toHexString(), "originalDefaultTimestamp", originalDefaultTimestamp.toString()) + assert.fieldEquals("LOANExtended", extendedEventId.toHexString(), "extendedDefaultTimestamp", extendedDefaultTimestamp.toString()) + }) + + test("handleExtensionProposalMade - creates a new ExtensionProposal entity", () => { + // First create a loan + const loanId = BigInt.fromI32(1) + const proposalHash = Bytes.fromHexString("0x1234") + const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") + const refinancingLoanId = BigInt.fromI32(0) + const lender = Address.fromString("0x0000000000000000000000000000000000000002") + const borrower = Address.fromString("0x0000000000000000000000000000000000000003") + const duration = BigInt.fromI32(30) + const createdAt = BigInt.fromI32(1234567890) + const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") + const collateralId = BigInt.fromI32(1) + const collateralCategory = 1 + const collateralAmount = BigInt.fromI32(100) + const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") + const creditId = BigInt.fromI32(0) + const creditCategory = 0 + const creditAmount = BigInt.fromI32(1000) + const fixedInterestAmount = BigInt.fromI32(50) + const accruingInterestAPR = 1000 + const lenderSpecHash = Bytes.fromHexString("0x5678") + const borrowerSpecHash = Bytes.fromHexString("0x9abc") + const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") + const extra = Bytes.fromHexString("0x1234") + const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + const createEvent = createLOANCreatedEvent( + loanId, + proposalHash, + proposalContract, + refinancingLoanId, + lender, + borrower, + duration, + createdAt, + collateralAssetAddress, + collateralId, + collateralCategory, + collateralAmount, + creditAssetAddress, + creditId, + creditCategory, + creditAmount, + fixedInterestAmount, + accruingInterestAPR, + lenderSpecHash, + borrowerSpecHash, + sourceOfFunds, + extra, + loanTokenAddress ) - assert.fieldEquals( - "ExtensionProposalMade", - "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", - "proposal", - "ethereum.Tuple Not implemented" + + handleLOANCreated(createEvent) + + // Then create an extension proposal + const extensionHash = Bytes.fromHexString("0xabcd") + const proposer = Address.fromString("0x0000000000000000000000000000000000000007") + const compensationAddress = Address.fromString("0x0000000000000000000000000000000000000008") + const compensationAmount = BigInt.fromI32(100) + const extensionDuration = BigInt.fromI32(15) + const expiration = BigInt.fromI32(1234567890 + 7) // 7 days from now + const nonceSpace = BigInt.fromI32(1) + const nonce = BigInt.fromI32(1) + + const extensionEvent = createExtensionProposalMadeEvent( + extensionHash, + proposer, + loanId, + compensationAddress, + compensationAmount, + extensionDuration, + expiration, + nonceSpace, + nonce, + loanTokenAddress ) + handleExtensionProposalMade(extensionEvent) - // More assert options: - // https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#asserts + // Verify the ExtensionProposal entity was created + assert.entityCount("ExtensionProposal", 1) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "proposer", proposer.toHexString()) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "compensationAssetAddress", compensationAddress.toHexString()) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "compensationAmount", compensationAmount.toString()) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "durationToExtend", extensionDuration.toString()) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "proposalExpiration", expiration.toString()) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "nonceSpace", nonceSpace.toString()) + assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "nonce", nonce.toString()) }) -}) +}) \ No newline at end of file From 5c0618a48061abf6506f2fa1bb1f021343ced93e Mon Sep 17 00:00:00 2001 From: microHoffman Date: Thu, 12 Jun 2025 13:28:06 +0200 Subject: [PATCH 10/13] test: make all tests work --- packages/subgraph/schema.graphql | 6 - .../simple-loan-elastic-chainlink-proposal.ts | 12 + .../subgraph/src/simple-loan-list-proposal.ts | 1 - .../src/simple-loan-simple-proposal.ts | 1 - packages/subgraph/tests/loan-token.test.ts | 12 +- packages/subgraph/tests/proposal-utils.ts | 21 +- packages/subgraph/tests/proposal.test.ts | 10 +- packages/subgraph/tests/simple-loan-utils.ts | 28 +- packages/subgraph/tests/simple-loan.test.ts | 388 ++++-------------- 9 files changed, 140 insertions(+), 339 deletions(-) diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 0f006c86..3ea5202a 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -249,7 +249,6 @@ type SimpleLoanSimpleProposalMade @entity(immutable: true) { durationOrDate: BigInt! # uint32 expiration: BigInt! # uint40 allowedAcceptor: Bytes! # address - proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) proposerSpecHash: Bytes! # bytes32 isOffer: Boolean! # bool refinancingLoanId: BigInt! # uint256 @@ -286,7 +285,6 @@ type SimpleLoanUniswapV3LPIndividualProposalProposalMade expiration: BigInt! # uint40 acceptorController: Bytes! # address acceptorControllerData: Bytes! # bytes - proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) proposerSpecHash: Bytes! # bytes32 isOffer: Boolean! # bool refinancingLoanId: BigInt! # uint256 @@ -322,7 +320,6 @@ type SimpleLoanUniswapV3LPSetProposalProposalMade @entity(immutable: true) { expiration: BigInt! # uint40 acceptorController: Bytes! # address acceptorControllerData: Bytes! # bytes - proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) proposerSpecHash: Bytes! # bytes32 isOffer: Boolean! # bool refinancingLoanId: BigInt! # uint256 @@ -358,7 +355,6 @@ type SimpleLoanListProposalProposalMade @entity(immutable: true) { durationOrDate: BigInt! # uint32 expiration: BigInt! # uint40 allowedAcceptor: Bytes! # address - proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) proposerSpecHash: Bytes! # bytes32 isOffer: Boolean! # bool refinancingLoanId: BigInt! # uint256 @@ -393,7 +389,6 @@ type SimpleLoanElasticProposalProposalMade @entity(immutable: true) { durationOrDate: BigInt! # uint32 expiration: BigInt! # uint40 allowedAcceptor: Bytes! # address - proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) proposerSpecHash: Bytes! # bytes32 isOffer: Boolean! # bool refinancingLoanId: BigInt! # uint256 @@ -430,7 +425,6 @@ type SimpleLoanElasticChainlinkProposalProposalMade @entity(immutable: true) { durationOrDate: BigInt! # uint32 expiration: BigInt! # uint40 allowedAcceptor: Bytes! # address - proposerAddress: Bytes! # address (renamed to avoid conflict with proposer field) proposerSpecHash: Bytes! # bytes32 isOffer: Boolean! # bool refinancingLoanId: BigInt! # uint256 diff --git a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts index c2422fb5..2acb6e2a 100644 --- a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts +++ b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts @@ -2,22 +2,30 @@ import { ProposalMade as ProposalMadeEvent } from "../generated/SimpleLoanElasti import { SimpleLoanElasticChainlinkProposalProposalMade, Proposal } from "../generated/schema" import { getOrCreateAsset } from "./utils" import { Bytes, BigInt } from "@graphprotocol/graph-ts" +import { log } from "@graphprotocol/graph-ts" export function handleProposalMade(event: ProposalMadeEvent): void { + log.info("aaaaaaaaaaaaaaaaaaa: {}", [event.params.proposalHash.toHexString()]) // Create the specific event entity const eventEntity = new SimpleLoanElasticChainlinkProposalProposalMade( event.transaction.hash.concatI32(event.logIndex.toI32()), ) eventEntity.proposalHash = event.params.proposalHash + log.info("bbbbbbbbbbbbbbbbbbbb: {}", [event.params.proposer.toString()]) + log.info("bbbbbbbbbbbbbbbbasddbbbb: {}", [event.params.proposal.proposer.toString()]) eventEntity.proposer = event.params.proposer eventEntity.collateralCategory = event.params.proposal.collateralCategory + log.info("xx: {}", [event.params.proposal.collateralAddress.toHexString()]) eventEntity.collateralAddress = event.params.proposal.collateralAddress eventEntity.collateralId = event.params.proposal.collateralId eventEntity.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint eventEntity.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint + log.info("dddddddddddddddddd: {}", [event.params.proposal.creditAddress.toHexString()]) eventEntity.creditAddress = event.params.proposal.creditAddress + log.info("xczxczxcc", []) + // log.info("eeeeeeeeeeeeeeeeee: {}", [event.params.proposal.feedIntermediaryDenominations[0].toString()]) eventEntity.feedIntermediaryDenominations = changetype( event.params.proposal.feedIntermediaryDenominations, ) @@ -26,6 +34,7 @@ export function handleProposalMade(event: ProposalMadeEvent): void { eventEntity.minCreditAmount = event.params.proposal.minCreditAmount eventEntity.availableCreditLimit = event.params.proposal.availableCreditLimit + log.info("fffffffffffffffffff: {}", [event.params.proposal.utilizedCreditId.toString()]) eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId eventEntity.fixedInterestAmount = event.params.proposal.fixedInterestAmount @@ -33,13 +42,16 @@ export function handleProposalMade(event: ProposalMadeEvent): void { event.params.proposal.accruingInterestAPR eventEntity.durationOrDate = event.params.proposal.durationOrDate eventEntity.expiration = event.params.proposal.expiration + log.info("gggggggggggggggggggg: {}", [event.params.proposal.allowedAcceptor.toString()]) eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor + log.info("hhhhhhhhhhhhhhhhhhh: {}", [event.params.proposal.proposer.toString()]) eventEntity.proposer = event.params.proposal.proposer eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash eventEntity.isOffer = event.params.proposal.isOffer eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId eventEntity.nonceSpace = event.params.proposal.nonceSpace eventEntity.nonce = event.params.proposal.nonce + log.info("iiiiiiiiiiiiiiiiiiii: {}", [event.params.proposal.loanContract.toString()]) eventEntity.loanContract = event.params.proposal.loanContract eventEntity.blockNumber = event.block.number diff --git a/packages/subgraph/src/simple-loan-list-proposal.ts b/packages/subgraph/src/simple-loan-list-proposal.ts index 2933a710..24da743f 100644 --- a/packages/subgraph/src/simple-loan-list-proposal.ts +++ b/packages/subgraph/src/simple-loan-list-proposal.ts @@ -31,7 +31,6 @@ export function handleProposalMade(event: ProposalMadeEvent): void { eventEntity.durationOrDate = event.params.proposal.durationOrDate eventEntity.expiration = event.params.proposal.expiration eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor - eventEntity.proposerAddress = event.params.proposal.proposer eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash eventEntity.isOffer = event.params.proposal.isOffer eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId diff --git a/packages/subgraph/src/simple-loan-simple-proposal.ts b/packages/subgraph/src/simple-loan-simple-proposal.ts index b3061c28..34a6f88c 100644 --- a/packages/subgraph/src/simple-loan-simple-proposal.ts +++ b/packages/subgraph/src/simple-loan-simple-proposal.ts @@ -30,7 +30,6 @@ export function handleProposalMade(event: ProposalMadeEvent): void { eventEntity.durationOrDate = event.params.proposal.durationOrDate eventEntity.expiration = event.params.proposal.expiration eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor - eventEntity.proposerAddress = event.params.proposal.proposer eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash eventEntity.isOffer = event.params.proposal.isOffer eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId diff --git a/packages/subgraph/tests/loan-token.test.ts b/packages/subgraph/tests/loan-token.test.ts index d727b9ce..34149992 100644 --- a/packages/subgraph/tests/loan-token.test.ts +++ b/packages/subgraph/tests/loan-token.test.ts @@ -4,7 +4,7 @@ import { handleTransfer } from "../src/loan-token" import { createTransferEvent } from "./loan-token-utils" import { getLoanId } from "../src/simple-loan" import { Loan } from "../generated/schema" -import { createDefaultTestLoan, TestLoanParams } from "./simple-loan-utils" +import { createTestLoan, TestLoanParams } from "./simple-loan-utils" import { log } from "matchstick-as/assembly/log" describe("LoanToken Events", () => { @@ -31,13 +31,11 @@ describe("LoanToken Events", () => { const loanParams = new TestLoanParams() loanParams.loanTokenAddress = loanTokenAddress loanParams.lender = from + loanParams.loanContractAddress = loanContractAddress - createMockedFunction(loanContractAddress, 'loanToken', 'loanToken():(address)') - .returns([ethereum.Value.fromAddress(loanTokenAddress)]) - - log.info("before createDefaultTestLoan", []) - createDefaultTestLoan(tokenId, loanParams) - log.info("after createDefaultTestLoan", []) + log.info("before createTestLoan", []) + createTestLoan(tokenId, loanParams) + log.info("after createTestLoan", []) assert.fieldEquals("Loan", loanId.toHexString(), "loanOwner", from.toHexString()) log.info("before createTransferEvent", []) diff --git a/packages/subgraph/tests/proposal-utils.ts b/packages/subgraph/tests/proposal-utils.ts index 5d435442..37dc0b32 100644 --- a/packages/subgraph/tests/proposal-utils.ts +++ b/packages/subgraph/tests/proposal-utils.ts @@ -46,6 +46,7 @@ export function createSimpleProposalMadeEvent( let proposalTuple = new ethereum.Tuple() proposalTuple.push(ethereum.Value.fromI32(collateralCategory)) proposalTuple.push(ethereum.Value.fromAddress(collateralAddress)) + proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralId)) proposalTuple.push(ethereum.Value.fromUnsignedBigInt(collateralAmount)) proposalTuple.push(ethereum.Value.fromBoolean(checkCollateralStateFingerprint)) proposalTuple.push(ethereum.Value.fromBytes(collateralStateFingerprint)) @@ -222,7 +223,7 @@ export function createElasticChainlinkProposalMadeEvent( checkCollateralStateFingerprint: boolean, collateralStateFingerprint: Bytes, creditAddress: Address, - feedIntermediaryDenominations: Bytes[], + feedIntermediaryDenominations: Address[], feedInvertFlags: boolean[], loanToValue: BigInt, minCreditAmount: BigInt, @@ -261,7 +262,7 @@ export function createElasticChainlinkProposalMadeEvent( let feedDenominationsArray = new Array() for (let i = 0; i < feedIntermediaryDenominations.length; i++) { - feedDenominationsArray.push(ethereum.Value.fromBytes(feedIntermediaryDenominations[i])) + feedDenominationsArray.push(ethereum.Value.fromAddress(feedIntermediaryDenominations[i])) } proposalTuple.push(ethereum.Value.fromArray(feedDenominationsArray)) @@ -303,7 +304,7 @@ export function createUniswapV3LPIndividualProposalMadeEvent( collateralId: BigInt, token0Denominator: Address, creditAddress: Address, - feedIntermediaryDenominations: Bytes[], + feedIntermediaryDenominations: Address[], feedInvertFlags: boolean[], loanToValue: BigInt, minCreditAmount: BigInt, @@ -340,7 +341,7 @@ export function createUniswapV3LPIndividualProposalMadeEvent( let feedDenominationsArray = new Array() for (let i = 0; i < feedIntermediaryDenominations.length; i++) { - feedDenominationsArray.push(ethereum.Value.fromBytes(feedIntermediaryDenominations[i])) + feedDenominationsArray.push(ethereum.Value.fromAddress(feedIntermediaryDenominations[i])) } proposalTuple.push(ethereum.Value.fromArray(feedDenominationsArray)) @@ -380,10 +381,10 @@ export function createUniswapV3LPIndividualProposalMadeEvent( export function createUniswapV3LPSetProposalMadeEvent( proposalHash: Bytes, proposer: Address, - tokenAAllowlist: Bytes[], - tokenBAllowlist: Bytes[], + tokenAAllowlist: Address[], + tokenBAllowlist: Address[], creditAddress: Address, - feedIntermediaryDenominations: Bytes[], + feedIntermediaryDenominations: Address[], feedInvertFlags: boolean[], loanToValue: BigInt, minCreditAmount: BigInt, @@ -417,13 +418,13 @@ export function createUniswapV3LPSetProposalMadeEvent( let tokenAArray = new Array() for (let i = 0; i < tokenAAllowlist.length; i++) { - tokenAArray.push(ethereum.Value.fromBytes(tokenAAllowlist[i])) + tokenAArray.push(ethereum.Value.fromAddress(tokenAAllowlist[i])) } proposalTuple.push(ethereum.Value.fromArray(tokenAArray)) let tokenBArray = new Array() for (let i = 0; i < tokenBAllowlist.length; i++) { - tokenBArray.push(ethereum.Value.fromBytes(tokenBAllowlist[i])) + tokenBArray.push(ethereum.Value.fromAddress(tokenBAllowlist[i])) } proposalTuple.push(ethereum.Value.fromArray(tokenBArray)) @@ -431,7 +432,7 @@ export function createUniswapV3LPSetProposalMadeEvent( let feedDenominationsArray = new Array() for (let i = 0; i < feedIntermediaryDenominations.length; i++) { - feedDenominationsArray.push(ethereum.Value.fromBytes(feedIntermediaryDenominations[i])) + feedDenominationsArray.push(ethereum.Value.fromAddress(feedIntermediaryDenominations[i])) } proposalTuple.push(ethereum.Value.fromArray(feedDenominationsArray)) diff --git a/packages/subgraph/tests/proposal.test.ts b/packages/subgraph/tests/proposal.test.ts index 02782483..49d1852f 100644 --- a/packages/subgraph/tests/proposal.test.ts +++ b/packages/subgraph/tests/proposal.test.ts @@ -230,7 +230,7 @@ describe("Proposal Events", () => { const checkCollateralStateFingerprint = true const collateralStateFingerprint = Bytes.fromHexString("0x5678") const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") - const feedIntermediaryDenominations = [Bytes.fromHexString("0x9abc")] + const feedIntermediaryDenominations = [Address.fromString("0x0000000000000000000000000000000000000023")] const feedInvertFlags = [true] const loanToValue = BigInt.fromI32(80) const minCreditAmount = BigInt.fromI32(100) @@ -299,7 +299,7 @@ describe("Proposal Events", () => { const collateralId = BigInt.fromI32(1) const token0Denominator = Address.fromString("0x0000000000000000000000000000000000000002") const creditAddress = Address.fromString("0x0000000000000000000000000000000000000003") - const feedIntermediaryDenominations = [Bytes.fromHexString("0x5678")] + const feedIntermediaryDenominations = [Address.fromString("0x0000000000000000000000000000000000000023")] const feedInvertFlags = [true] const loanToValue = BigInt.fromI32(80) const minCreditAmount = BigInt.fromI32(100) @@ -364,10 +364,10 @@ describe("Proposal Events", () => { test("handleUniswapV3LPSetProposalMade - creates a new Proposal entity", () => { const proposalHash = Bytes.fromHexString("0x1234") const proposer = Address.fromString("0x0000000000000000000000000000000000000001") - const tokenAAllowlist = [Bytes.fromHexString("0x5678")] - const tokenBAllowlist = [Bytes.fromHexString("0x9abc")] + const tokenAAllowlist = [Address.fromString("0x0000000000000000000000000000000000000033")] + const tokenBAllowlist = [Address.fromString("0x0000000000000000000000000000000000000043")] const creditAddress = Address.fromString("0x0000000000000000000000000000000000000002") - const feedIntermediaryDenominations = [Bytes.fromHexString("0xdef0")] + const feedIntermediaryDenominations = [Address.fromString("0x0000000000000000000000000000000000000023")] const feedInvertFlags = [true] const loanToValue = BigInt.fromI32(80) const minCreditAmount = BigInt.fromI32(100) diff --git a/packages/subgraph/tests/simple-loan-utils.ts b/packages/subgraph/tests/simple-loan-utils.ts index de997614..c8de27d2 100644 --- a/packages/subgraph/tests/simple-loan-utils.ts +++ b/packages/subgraph/tests/simple-loan-utils.ts @@ -1,6 +1,6 @@ import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" import { LOANCreated, LOANPaidBack, LOANClaimed, LOANExtended, ExtensionProposalMade } from "../generated/SimpleLoan/SimpleLoan" -import { assert, test, newMockEvent, dataSourceMock } from 'matchstick-as/assembly/index' +import { assert, test, newMockEvent, dataSourceMock, createMockedFunction } from 'matchstick-as/assembly/index' import { handleLOANCreated } from "../src/simple-loan" import { Loan } from "../generated/schema"; @@ -28,9 +28,10 @@ export class TestLoanParams { sourceOfFunds: Address = Address.fromString("0x0000000000000000000000000000000000000003"); extra: Bytes = Bytes.fromHexString("0x1234"); loanTokenAddress: Address = Address.fromString("0x0000000000000000000000000000000000000006"); + loanContractAddress: Address = Address.fromString("0x0000000000000000000000000000000000000007"); } -export function createDefaultTestLoan(loanId: BigInt, params: TestLoanParams | null = null): Loan { +export function createTestLoan(loanId: BigInt, params: TestLoanParams | null = null): Loan { // Use default params if none provided const p = params ? params : new TestLoanParams(); @@ -57,9 +58,12 @@ export function createDefaultTestLoan(loanId: BigInt, params: TestLoanParams | n p.borrowerSpecHash, p.sourceOfFunds, p.extra, - p.loanTokenAddress + p.loanContractAddress ); + createMockedFunction(p.loanContractAddress, 'loanToken', 'loanToken():(address)') + .returns([ethereum.Value.fromAddress(p.loanTokenAddress)]) + const loan = handleLOANCreated(createEvent); return loan; } @@ -87,7 +91,7 @@ export function createLOANCreatedEvent( borrowerSpecHash: Bytes, sourceOfFunds: Address, extra: Bytes, - loanTokenAddress: Address + loanContractAddress: Address ): LOANCreated { let event = changetype(newMockEvent()) @@ -133,8 +137,9 @@ export function createLOANCreatedEvent( new ethereum.EventParam("extra", ethereum.Value.fromBytes(extra)) ) - // TODO is this fine or we should also pass the loan contract address and set it here? - // event.address = loanContractAddress + event.block.timestamp = createdAt + + event.address = loanContractAddress return event } @@ -204,7 +209,7 @@ function createLenderSpecTuple( export function createLOANClaimedEvent( loanId: BigInt, defaulted: boolean, - loanTokenAddress: Address + loanContractAddress: Address ): LOANClaimed { let event = changetype(newMockEvent()) @@ -218,7 +223,7 @@ export function createLOANClaimedEvent( ) // Mock the loanToken() call - event.address = loanTokenAddress + event.address = loanContractAddress return event } @@ -316,7 +321,7 @@ function createExtensionProposalTuple( export function createLOANPaidBackEvent( loanId: BigInt, paidBackAt: BigInt, - loanTokenAddress: Address + loanContractAddress: Address ): LOANPaidBack { let event = changetype(newMockEvent()) @@ -328,9 +333,10 @@ export function createLOANPaidBackEvent( event.parameters.push( new ethereum.EventParam("paidBackAt", ethereum.Value.fromUnsignedBigInt(paidBackAt)) ) + + event.block.timestamp = paidBackAt - // Mock the loanToken() call - event.address = loanTokenAddress + event.address = loanContractAddress return event } diff --git a/packages/subgraph/tests/simple-loan.test.ts b/packages/subgraph/tests/simple-loan.test.ts index d744d8ba..a5b2967d 100644 --- a/packages/subgraph/tests/simple-loan.test.ts +++ b/packages/subgraph/tests/simple-loan.test.ts @@ -1,7 +1,8 @@ import { assert, describe, test, clearStore, beforeEach, afterEach } from "matchstick-as/assembly/index" import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts" -import { handleLOANCreated, handleLOANPaidBack, handleLOANClaimed, handleLOANExtended, handleExtensionProposalMade } from "../src/simple-loan" -import { createLOANCreatedEvent, createLOANPaidBackEvent, createLOANClaimedEvent, createLOANExtendedEvent, createExtensionProposalMadeEvent } from "./simple-loan-utils" +import { handleLOANPaidBack, handleLOANClaimed, handleLOANExtended, handleExtensionProposalMade, getLoanId } from "../src/simple-loan" +import { createTestLoan, createLOANPaidBackEvent, createLOANClaimedEvent, createLOANExtendedEvent, createExtensionProposalMadeEvent, TestLoanParams } from "./simple-loan-utils" +import { log } from "matchstick-as/assembly/log" describe("SimpleLoan", () => { beforeEach(() => { @@ -14,359 +15,150 @@ describe("SimpleLoan", () => { test("handleLOANCreated - creates a new Loan entity", () => { const loanId = BigInt.fromI32(1) - const proposalHash = Bytes.fromHexString("0x1234") - const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") - const refinancingLoanId = BigInt.fromI32(0) - const lender = Address.fromString("0x0000000000000000000000000000000000000002") - const borrower = Address.fromString("0x0000000000000000000000000000000000000003") - const duration = BigInt.fromI32(30) - const createdAt = BigInt.fromI32(1234567890) - const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") - const collateralId = BigInt.fromI32(1) - const collateralCategory = 1 - const collateralAmount = BigInt.fromI32(100) - const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") - const creditId = BigInt.fromI32(0) - const creditCategory = 0 - const creditAmount = BigInt.fromI32(1000) - const fixedInterestAmount = BigInt.fromI32(50) - const accruingInterestAPR = 1000 - const lenderSpecHash = Bytes.fromHexString("0x5678") - const borrowerSpecHash = Bytes.fromHexString("0x9abc") - const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") - const extra = Bytes.fromHexString("0x1234") const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") - - const event = createLOANCreatedEvent( - loanId, - proposalHash, - proposalContract, - refinancingLoanId, - lender, - borrower, - duration, - createdAt, - collateralAssetAddress, - collateralId, - collateralCategory, - collateralAmount, - creditAssetAddress, - creditId, - creditCategory, - creditAmount, - fixedInterestAmount, - accruingInterestAPR, - lenderSpecHash, - borrowerSpecHash, - sourceOfFunds, - extra, - loanTokenAddress - ) - - handleLOANCreated(event) - - const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) + const loanContractAddress = Address.fromString("0x0000000000000000000000000000000000000007") + + // Create test parameters with explicit values we want to test + const params = new TestLoanParams() + params.proposalHash = Bytes.fromHexString("0x1234") + params.lender = Address.fromString("0x0000000000000000000000000000000000000002") + params.borrower = Address.fromString("0x0000000000000000000000000000000000000003") + params.duration = BigInt.fromI32(30) + params.createdAt = BigInt.fromI32(1234567890) + params.loanContractAddress = loanContractAddress + params.loanTokenAddress = loanTokenAddress + + const loan = createTestLoan(loanId, params) + + const loanEntityId = getLoanId(loanContractAddress, loanId).toHexString() assert.entityCount("Loan", 1) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "loanId", loanId.toString()) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "proposalHash", proposalHash.toHexString()) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "originalLender", lender.toHexString()) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "borrower", borrower.toHexString()) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "duration", duration.toString()) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "createdAt", createdAt.toString()) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "status", "Active") + assert.fieldEquals("Loan", loanEntityId, "loanId", loanId.toString()) + assert.fieldEquals("Loan", loanEntityId, "proposalHash", params.proposalHash.toHexString()) + assert.fieldEquals("Loan", loanEntityId, "originalLender", params.lender.toHexString()) + assert.fieldEquals("Loan", loanEntityId, "borrower", params.borrower.toHexString()) + assert.fieldEquals("Loan", loanEntityId, "duration", params.duration.toString()) + assert.fieldEquals("Loan", loanEntityId, "createdAt", params.createdAt.toString()) + assert.fieldEquals("Loan", loanEntityId, "status", "Active") + assert.fieldEquals("Loan", loanEntityId, "loanTokenAddress", loanTokenAddress.toHexString()) }) test("handleLOANPaidBack - updates Loan status to Repaid", () => { - // First create a loan const loanId = BigInt.fromI32(1) - const proposalHash = Bytes.fromHexString("0x1234") - const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") - const refinancingLoanId = BigInt.fromI32(0) - const lender = Address.fromString("0x0000000000000000000000000000000000000002") - const borrower = Address.fromString("0x0000000000000000000000000000000000000003") - const duration = BigInt.fromI32(30) - const createdAt = BigInt.fromI32(1234567890) - const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") - const collateralId = BigInt.fromI32(1) - const collateralCategory = 1 - const collateralAmount = BigInt.fromI32(100) - const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") - const creditId = BigInt.fromI32(0) - const creditCategory = 0 - const creditAmount = BigInt.fromI32(1000) - const fixedInterestAmount = BigInt.fromI32(50) - const accruingInterestAPR = 1000 - const lenderSpecHash = Bytes.fromHexString("0x5678") - const borrowerSpecHash = Bytes.fromHexString("0x9abc") - const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") - const extra = Bytes.fromHexString("0x1234") - const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") - - const createEvent = createLOANCreatedEvent( - loanId, - proposalHash, - proposalContract, - refinancingLoanId, - lender, - borrower, - duration, - createdAt, - collateralAssetAddress, - collateralId, - collateralCategory, - collateralAmount, - creditAssetAddress, - creditId, - creditCategory, - creditAmount, - fixedInterestAmount, - accruingInterestAPR, - lenderSpecHash, - borrowerSpecHash, - sourceOfFunds, - extra, - loanTokenAddress - ) - - handleLOANCreated(createEvent) + + // Create test parameters with explicit values + const params = new TestLoanParams() + params.createdAt = BigInt.fromI32(1234567890) + + // Create the loan + createTestLoan(loanId, params) // Then pay it back const paidBackAt = BigInt.fromI32(1234567891) - const payBackEvent = createLOANPaidBackEvent(loanId, paidBackAt, loanTokenAddress) + const payBackEvent = createLOANPaidBackEvent(loanId, paidBackAt, params.loanContractAddress) handleLOANPaidBack(payBackEvent) - const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) + const loanIdBytes = params.loanContractAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) assert.fieldEquals("Loan", loanIdBytes.toHexString(), "status", "Repaid") assert.fieldEquals("Loan", loanIdBytes.toHexString(), "repaidAt", paidBackAt.toString()) }) test("handleLOANClaimed - updates Loan status to Claimed", () => { - // First create a loan const loanId = BigInt.fromI32(1) - const proposalHash = Bytes.fromHexString("0x1234") - const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") - const refinancingLoanId = BigInt.fromI32(0) - const lender = Address.fromString("0x0000000000000000000000000000000000000002") - const borrower = Address.fromString("0x0000000000000000000000000000000000000003") - const duration = BigInt.fromI32(30) - const createdAt = BigInt.fromI32(1234567890) - const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") - const collateralId = BigInt.fromI32(1) - const collateralCategory = 1 - const collateralAmount = BigInt.fromI32(100) - const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") - const creditId = BigInt.fromI32(0) - const creditCategory = 0 - const creditAmount = BigInt.fromI32(1000) - const fixedInterestAmount = BigInt.fromI32(50) - const accruingInterestAPR = 1000 - const lenderSpecHash = Bytes.fromHexString("0x5678") - const borrowerSpecHash = Bytes.fromHexString("0x9abc") - const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") - const extra = Bytes.fromHexString("0x1234") - const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") - - const createEvent = createLOANCreatedEvent( - loanId, - proposalHash, - proposalContract, - refinancingLoanId, - lender, - borrower, - duration, - createdAt, - collateralAssetAddress, - collateralId, - collateralCategory, - collateralAmount, - creditAssetAddress, - creditId, - creditCategory, - creditAmount, - fixedInterestAmount, - accruingInterestAPR, - lenderSpecHash, - borrowerSpecHash, - sourceOfFunds, - extra, - loanTokenAddress - ) - - handleLOANCreated(createEvent) + + // Create test parameters with explicit values + const params = new TestLoanParams() + params.createdAt = BigInt.fromI32(1234567890) + + // Create the loan + createTestLoan(loanId, params) // Then claim it const defaulted = true - const claimEvent = createLOANClaimedEvent(loanId, defaulted, loanTokenAddress) + const claimEvent = createLOANClaimedEvent(loanId, defaulted, params.loanContractAddress) handleLOANClaimed(claimEvent) - const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "status", "Claimed") - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "hasDefaulted", defaulted.toString()) + const loanEntityId = getLoanId(params.loanContractAddress, loanId).toHexString() + log.info("loanEntityId: {}", [loanEntityId]) + log.info("params.loanContractAddress: {}", [params.loanContractAddress.toHexString()]) + + assert.fieldEquals("Loan", loanEntityId, "status", "Claimed") + assert.fieldEquals("Loan", loanEntityId, "hasDefaulted", defaulted.toString()) }) test("handleLOANExtended - extends loan duration and updates default date", () => { - // First create a loan const loanId = BigInt.fromI32(1) - const proposalHash = Bytes.fromHexString("0x1234") - const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") - const refinancingLoanId = BigInt.fromI32(0) - const lender = Address.fromString("0x0000000000000000000000000000000000000002") - const borrower = Address.fromString("0x0000000000000000000000000000000000000003") - const duration = BigInt.fromI32(30) - const createdAt = BigInt.fromI32(1234567890) - const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") - const collateralId = BigInt.fromI32(1) - const collateralCategory = 1 - const collateralAmount = BigInt.fromI32(100) - const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") - const creditId = BigInt.fromI32(0) - const creditCategory = 0 - const creditAmount = BigInt.fromI32(1000) - const fixedInterestAmount = BigInt.fromI32(50) - const accruingInterestAPR = 1000 - const lenderSpecHash = Bytes.fromHexString("0x5678") - const borrowerSpecHash = Bytes.fromHexString("0x9abc") - const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") - const extra = Bytes.fromHexString("0x1234") - const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") - - const createEvent = createLOANCreatedEvent( - loanId, - proposalHash, - proposalContract, - refinancingLoanId, - lender, - borrower, - duration, - createdAt, - collateralAssetAddress, - collateralId, - collateralCategory, - collateralAmount, - creditAssetAddress, - creditId, - creditCategory, - creditAmount, - fixedInterestAmount, - accruingInterestAPR, - lenderSpecHash, - borrowerSpecHash, - sourceOfFunds, - extra, - loanTokenAddress - ) - - handleLOANCreated(createEvent) + const loanContractAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + // Create test parameters with explicit values + const params = new TestLoanParams() + params.createdAt = BigInt.fromI32(1234567890) + params.duration = BigInt.fromI32(30) + params.loanContractAddress = loanContractAddress + + // Create the loan + createTestLoan(loanId, params) // Then extend it - const originalDefaultTimestamp = BigInt.fromI32(1234567920) // 30 days after creation - const extendedDefaultTimestamp = BigInt.fromI32(1234567920 + 15) // 15 more days + const originalDefaultTimestamp = params.createdAt.plus(params.duration) // createdAt + duration + const extendedDefaultTimestamp = originalDefaultTimestamp.plus(BigInt.fromI32(30)) // originalDefaultTimestamp + 30 const extendEvent = createLOANExtendedEvent( loanId, originalDefaultTimestamp, extendedDefaultTimestamp, - loanTokenAddress + loanContractAddress ) handleLOANExtended(extendEvent) - const loanIdBytes = loanTokenAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "duration", "45") // 30 + 15 days - assert.fieldEquals("Loan", loanIdBytes.toHexString(), "defaultDate", extendedDefaultTimestamp.toString()) - - // Also verify the LOANExtended entity was created - const extendedEventId = extendEvent.transaction.hash.concatI32(extendEvent.logIndex.toI32()) - assert.entityCount("LOANExtended", 1) - assert.fieldEquals("LOANExtended", extendedEventId.toHexString(), "loanId", loanId.toString()) - assert.fieldEquals("LOANExtended", extendedEventId.toHexString(), "originalDefaultTimestamp", originalDefaultTimestamp.toString()) - assert.fieldEquals("LOANExtended", extendedEventId.toHexString(), "extendedDefaultTimestamp", extendedDefaultTimestamp.toString()) + const loanEntityId = getLoanId(loanContractAddress, loanId).toHexString() + assert.fieldEquals("Loan", loanEntityId, "defaultDate", extendedDefaultTimestamp.toString()) }) test("handleExtensionProposalMade - creates a new ExtensionProposal entity", () => { - // First create a loan const loanId = BigInt.fromI32(1) - const proposalHash = Bytes.fromHexString("0x1234") - const proposalContract = Address.fromString("0x0000000000000000000000000000000000000001") - const refinancingLoanId = BigInt.fromI32(0) - const lender = Address.fromString("0x0000000000000000000000000000000000000002") - const borrower = Address.fromString("0x0000000000000000000000000000000000000003") - const duration = BigInt.fromI32(30) - const createdAt = BigInt.fromI32(1234567890) - const collateralAssetAddress = Address.fromString("0x0000000000000000000000000000000000000004") - const collateralId = BigInt.fromI32(1) - const collateralCategory = 1 - const collateralAmount = BigInt.fromI32(100) - const creditAssetAddress = Address.fromString("0x0000000000000000000000000000000000000005") - const creditId = BigInt.fromI32(0) - const creditCategory = 0 - const creditAmount = BigInt.fromI32(1000) - const fixedInterestAmount = BigInt.fromI32(50) - const accruingInterestAPR = 1000 - const lenderSpecHash = Bytes.fromHexString("0x5678") - const borrowerSpecHash = Bytes.fromHexString("0x9abc") - const sourceOfFunds = Address.fromString("0x0000000000000000000000000000000000000003") - const extra = Bytes.fromHexString("0x1234") - const loanTokenAddress = Address.fromString("0x0000000000000000000000000000000000000006") + const loanContractAddress = Address.fromString("0x0000000000000000000000000000000000000006") + + // Create test parameters with explicit values + const params = new TestLoanParams() + params.createdAt = BigInt.fromI32(1234567890) + params.loanContractAddress = loanContractAddress - const createEvent = createLOANCreatedEvent( - loanId, - proposalHash, - proposalContract, - refinancingLoanId, - lender, - borrower, - duration, - createdAt, - collateralAssetAddress, - collateralId, - collateralCategory, - collateralAmount, - creditAssetAddress, - creditId, - creditCategory, - creditAmount, - fixedInterestAmount, - accruingInterestAPR, - lenderSpecHash, - borrowerSpecHash, - sourceOfFunds, - extra, - loanTokenAddress - ) - - handleLOANCreated(createEvent) + // Create the loan + createTestLoan(loanId, params) // Then create an extension proposal const extensionHash = Bytes.fromHexString("0xabcd") - const proposer = Address.fromString("0x0000000000000000000000000000000000000007") - const compensationAddress = Address.fromString("0x0000000000000000000000000000000000000008") + const proposer = Address.fromString("0x0000000000000000000000000000000000000008") + const compensationAddress = Address.fromString("0x0000000000000000000000000000000000000009") const compensationAmount = BigInt.fromI32(100) - const extensionDuration = BigInt.fromI32(15) - const expiration = BigInt.fromI32(1234567890 + 7) // 7 days from now + const duration = BigInt.fromI32(30) + const expiration = BigInt.fromI32(1234567899) const nonceSpace = BigInt.fromI32(1) const nonce = BigInt.fromI32(1) - const extensionEvent = createExtensionProposalMadeEvent( + const proposalEvent = createExtensionProposalMadeEvent( extensionHash, proposer, loanId, compensationAddress, compensationAmount, - extensionDuration, + duration, expiration, nonceSpace, nonce, - loanTokenAddress + loanContractAddress ) - handleExtensionProposalMade(extensionEvent) + handleExtensionProposalMade(proposalEvent) - // Verify the ExtensionProposal entity was created + const loanEntityId = getLoanId(loanContractAddress, loanId).toHexString() + const proposalId = extensionHash.toHexString() assert.entityCount("ExtensionProposal", 1) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "proposer", proposer.toHexString()) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "compensationAssetAddress", compensationAddress.toHexString()) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "compensationAmount", compensationAmount.toString()) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "durationToExtend", extensionDuration.toString()) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "proposalExpiration", expiration.toString()) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "nonceSpace", nonceSpace.toString()) - assert.fieldEquals("ExtensionProposal", extensionHash.toHexString(), "nonce", nonce.toString()) + assert.fieldEquals("ExtensionProposal", proposalId, "loan", loanEntityId) + assert.fieldEquals("ExtensionProposal", proposalId, "proposer", proposer.toHexString()) + assert.fieldEquals("ExtensionProposal", proposalId, "compensationAssetAddress", compensationAddress.toHexString()) + assert.fieldEquals("ExtensionProposal", proposalId, "compensationAmount", compensationAmount.toString()) + assert.fieldEquals("ExtensionProposal", proposalId, "durationToExtend", duration.toString()) + assert.fieldEquals("ExtensionProposal", proposalId, "proposalExpiration", expiration.toString()) + assert.fieldEquals("ExtensionProposal", proposalId, "nonceSpace", nonceSpace.toString()) + assert.fieldEquals("ExtensionProposal", proposalId, "nonce", nonce.toString()) }) }) \ No newline at end of file From 61487af1c3d4d172a278046d22a814b46a8bdfe1 Mon Sep 17 00:00:00 2001 From: microHoffman Date: Fri, 13 Jun 2025 12:39:19 +0200 Subject: [PATCH 11/13] feat: update subgraph specVersion to 1.2.0 --- packages/subgraph/package.json | 3 +- packages/subgraph/subgraph.template.yaml | 2 +- packages/subgraph/subgraph.yaml | 362 ----------------------- packages/subgraph/tests/.latest.json | 2 +- 4 files changed, 4 insertions(+), 365 deletions(-) delete mode 100644 packages/subgraph/subgraph.yaml diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index 8679e19d..83ca0fb7 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -19,11 +19,12 @@ "prepare:sepolia": "mustache config/sepolia.json subgraph.template.yaml > subgraph.yaml", "codegen": "nx exec -- graph codegen", "build": "nx exec -- graph build", - "deploy": "nx exec -- graph deploy pwn-test-proposals subgraph.yaml", + "deploy": "nx exec -- graph deploy pwndao-test-subgraph subgraph.yaml", "create-local": "nx exec -- graph create --node http://localhost:8020/ pwn-test-proposals", "remove-local": "nx exec -- graph remove --node http://localhost:8020/ pwn-test-proposals", "deploy-local": "nx exec -- graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 pwn-test-proposals", "docker-prepare": "docker build -t matchstick .", + "auth-subgraph-studio": "graph auth", "test:with-docker": "nx exec -- graph test -d", "test": "nx exec -- graph test", "help": "nx exec -- graph test --help" diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index 26d569ce..999d19e4 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -1,4 +1,4 @@ -specVersion: 0.0.5 +specVersion: 1.2.0 schema: file: ./schema.graphql dataSources: diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml deleted file mode 100644 index bf0f9c82..00000000 --- a/packages/subgraph/subgraph.yaml +++ /dev/null @@ -1,362 +0,0 @@ -specVersion: 0.0.5 -schema: - file: ./schema.graphql -dataSources: - # TODO should we also include: - # - RevokedNonce ? - # - Config? - # - Hub? - # - SimpleLoanDutchAuction? - - # TODO go over the events here and see what we can remove - - kind: ethereum - name: SimpleLoanSimpleProposal - network: sepolia - source: - address: "0xe624E7D33baC728bE2bdB606Da0018B6E05A84D9" - abi: SimpleLoanSimpleProposal - startBlock: 7298850 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - ProposalMade - abis: - - name: SimpleLoanSimpleProposal - file: ./abis/SimpleLoanSimpleProposal.json - eventHandlers: - - event: ProposalMade(indexed bytes32,indexed - address,(uint8,address,uint256,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) - handler: handleProposalMade - file: ./src/simple-loan-simple-proposal.ts - - kind: ethereum - name: SimpleLoanListProposal - network: sepolia - source: - address: "0x7160Ec33788Df9AFb8AAEe777e7Ae21151B51eDd" - abi: SimpleLoanListProposal - startBlock: 7298850 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - SimpleLoanListProposalProposalMade - abis: - - name: SimpleLoanListProposal - file: ./abis/SimpleLoanListProposal.json - eventHandlers: - - event: ProposalMade(indexed bytes32,indexed - address,(uint8,address,bytes32,uint256,bool,bytes32,address,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) - handler: handleProposalMade - file: ./src/simple-loan-list-proposal.ts - - kind: ethereum - name: SimpleLoanElasticProposal - network: sepolia - source: - address: "0xeC6390D4B22FFfD22E5C5FDB56DaF653C3Cd0626" - abi: SimpleLoanElasticProposal - startBlock: 7298851 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - SimpleLoanElasticProposalProposalMade - abis: - - name: SimpleLoanElasticProposal - file: ./abis/SimpleLoanElasticProposal.json - eventHandlers: - - event: ProposalMade(indexed bytes32,indexed - address,(uint8,address,uint256,bool,bytes32,address,uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) - handler: handleProposalMade - file: ./src/simple-loan-elastic-proposal.ts - - kind: ethereum - name: SimpleLoanElasticChainlinkProposal - network: sepolia - source: - address: "0xC46170F43b97faE1A8B507d6fdDaFfBb7527D61B" - abi: SimpleLoanElasticChainlinkProposal - startBlock: 8069855 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - SimpleLoanElasticChainlinkProposalProposalMade - abis: - - name: SimpleLoanElasticChainlinkProposal - file: ./abis/SimpleLoanElasticChainlinkProposal.json - eventHandlers: - - event: ProposalMade(indexed bytes32,indexed - address,(uint8,address,uint256,bool,bytes32,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,address,bytes32,bool,uint256,uint256,uint256,address)) - handler: handleProposalMade - file: ./src/simple-loan-elastic-chainlink-proposal.ts - - kind: ethereum - name: SimpleLoan - network: sepolia - source: - address: "0x719A69d0dc67bd3Aa7648D4694081B3c87952797" - abi: SimpleLoan - startBlock: 7298850 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - ExtensionProposalMade - - LOANClaimed - - LOANCreated - - LOANExtended - - LOANPaidBack - #- PoolSupply - #- PoolWithdraw - #- VaultPull - #- VaultPush - #- VaultPushFrom - abis: - - name: SimpleLoan - file: ./abis/SimpleLoan.json - eventHandlers: - - event: ExtensionProposalMade(indexed bytes32,indexed - address,(uint256,address,uint256,uint40,uint40,address,uint256,uint256)) - handler: handleExtensionProposalMade - - event: LOANClaimed(indexed uint256,indexed bool) - handler: handleLOANClaimed - - event: LOANCreated(indexed uint256,indexed bytes32,indexed - address,uint256,(address,address,uint32,(uint8,address,uint256,uint256),(uint8,address,uint256,uint256),uint256,uint24,bytes32,bytes32),(address),bytes) - handler: handleLOANCreated - - event: LOANExtended(indexed uint256,uint40,uint40) - handler: handleLOANExtended - - event: LOANPaidBack(indexed uint256) - handler: handleLOANPaidBack - #- event: PoolSupply((uint8,address,uint256,uint256),indexed address,indexed address,indexed - # address) - # handler: handlePoolSupply - #- event: PoolWithdraw((uint8,address,uint256,uint256),indexed address,indexed - # address,indexed address) - # handler: handlePoolWithdraw - #- event: VaultPull((uint8,address,uint256,uint256),indexed address) - # handler: handleVaultPull - #- event: VaultPush((uint8,address,uint256,uint256),indexed address) - # handler: handleVaultPush - #- event: VaultPushFrom((uint8,address,uint256,uint256),indexed address,indexed address) - # handler: handleVaultPushFrom - file: ./src/simple-loan.ts - - kind: ethereum - name: LoanToken - network: sepolia - source: - address: "0x4440C069272cC34b80C7B11bEE657D0349Ba9C23" - abi: LoanToken - startBlock: 4435806 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - # - Approval - # - ApprovalForAll - #- LOANBurned - #- LOANMinted - - Transfer - abis: - - name: LoanToken - file: ./abis/LoanToken.json - eventHandlers: - # - event: Approval(indexed address,indexed address,indexed uint256) - # handler: handleApproval - # - event: ApprovalForAll(indexed address,indexed address,bool) - # handler: handleApprovalForAll - # note: no need to track LOANBurned and LOANMinted as they happen always - # together with LOANCreated and LOANClaimed - #- event: LOANBurned(indexed uint256) - # handler: handleLOANBurned - #- event: LOANMinted(indexed uint256,indexed address,indexed address) - # handler: handleLOANMinted - - event: Transfer(indexed address,indexed address,indexed uint256) - handler: handleTransfer - file: ./src/loan-token.ts - # TODO update Config abi - # TODO should we also have proxy upgrade events in the config address? - # - kind: ethereum - # name: Config - # network: sepolia - # source: - # address: "0xd52a2898d61636bB3eEF0d145f05352FF543bdCC" - # abi: Config - # startBlock: 5953668 - # mapping: - # kind: ethereum/events - # apiVersion: 0.0.9 - # language: wasm/assemblyscript - # entities: - # #- AdminChanged - # #- BeaconUpgraded - # #- Upgraded - # - DefaultLOANMetadataUriUpdated - # - FeeCollectorUpdated - # - FeeUpdated - # #- Initialized - # - LOANMetadataUriUpdated - # #- ConfigOwnershipTransferStarted - # #- ConfigOwnershipTransferred - # abis: - # - name: Config - # file: ./abis/Config.json - # eventHandlers: - # #- event: AdminChanged(address,address) - # # handler: handleAdminChanged - # #- event: BeaconUpgraded(indexed address) - # # handler: handleBeaconUpgraded - # #- event: Upgraded(indexed address) - # # handler: handleUpgraded - # - event: DefaultLOANMetadataUriUpdated(string) - # handler: handleDefaultLOANMetadataUriUpdated - # - event: FeeCollectorUpdated(address,address) - # handler: handleFeeCollectorUpdated - # - event: FeeUpdated(uint16,uint16) - # handler: handleFeeUpdated - # #- event: Initialized(uint8) - # # handler: handleInitialized - # - event: LOANMetadataUriUpdated(indexed address,string) - # handler: handleLOANMetadataUriUpdated - # #- event: OwnershipTransferStarted(indexed address,indexed address) - # # handler: handleOwnershipTransferStarted - # #- event: OwnershipTransferred(indexed address,indexed address) - # # handler: handleOwnershipTransferred - # file: ./src/config.ts - - kind: ethereum - name: Hub - network: sepolia - source: - address: "0x37807A2F031b3B44081F4b21500E5D70EbaDAdd5" - abi: Hub - startBlock: 4435806 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - #- OwnershipTransferStarted - #- OwnershipTransferred - - TagSet - abis: - - name: Hub - file: ./abis/Hub.json - eventHandlers: - #- event: OwnershipTransferStarted(indexed address,indexed address) - # handler: handleOwnershipTransferStarted - #- event: OwnershipTransferred(indexed address,indexed address) - # handler: handleOwnershipTransferred - - event: TagSet(indexed address,indexed bytes32,bool) - handler: handleTagSet - file: ./src/hub.ts - - kind: ethereum - name: ChainlinkFeedRegistry - network: sepolia - source: - address: "0x8D5e90706E52a52853dA9A14fA1c63889a412851" - abi: ChainlinkFeedRegistry - startBlock: 7298850 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - #- AccessControllerSet - - ChainlinkFeed - #- FeedConfirmed - #- FeedProposed - #- OwnershipTransferRequested - #- ChainlinkFeedRegistryOwnershipTransferred - abis: - - name: ChainlinkFeedRegistry - file: ./abis/ChainlinkFeedRegistry.json - eventHandlers: - #- event: AccessControllerSet(indexed address,indexed address) - # handler: handleAccessControllerSet - - event: FeedConfirmed(indexed address,indexed address,indexed - address,address,uint16,address) - handler: handleFeedConfirmed - #- event: FeedProposed(indexed address,indexed address,indexed address,address,address) - # handler: handleFeedProposed - #- event: OwnershipTransferRequested(indexed address,indexed address) - # handler: handleOwnershipTransferRequested - #- event: OwnershipTransferred(indexed address,indexed address) - # handler: handleOwnershipTransferred - file: ./src/chainlink-feed-registry.ts - - kind: ethereum - name: MultiTokenCategoryRegistry - network: sepolia - source: - address: "0xbB2168d5546A94AE2DA9254e63D88F7f137B2534" - abi: MultiTokenCategoryRegistry - startBlock: 5953672 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - AssetInCategory - - Category - #- CategoryRegistered - #- CategoryUnregistered - #- MultiTokenCategoryRegistryOwnershipTransferStarted - #- MultiTokenCategoryRegistryOwnershipTransferred - abis: - - name: MultiTokenCategoryRegistry - file: ./abis/MultiTokenCategoryRegistry.json - eventHandlers: - - event: CategoryRegistered(indexed address,indexed uint8) - handler: handleCategoryRegistered - - event: CategoryUnregistered(indexed address) - handler: handleCategoryUnregistered - #- event: OwnershipTransferStarted(indexed address,indexed address) - # handler: handleOwnershipTransferStarted - #- event: OwnershipTransferred(indexed address,indexed address) - # handler: handleOwnershipTransferred - file: ./src/multi-token-category-registry.ts - - kind: ethereum - name: SimpleLoanUniswapV3LPIndividualProposal - network: sepolia - source: - address: "0xF966696BE0623447679AC830FC5bB7bDB15FEAB4" - abi: SimpleLoanUniswapV3LPIndividualProposal - startBlock: 8518575 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - SimpleLoanUniswapV3LPIndividualProposalProposalMade - abis: - - name: SimpleLoanUniswapV3LPIndividualProposal - file: ./abis/SimpleLoanUniswapV3LPIndividualProposal.json - eventHandlers: - - event: ProposalMade(indexed bytes32,indexed - address,(uint256,bool,address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) - handler: handleProposalMade - file: ./src/simple-loan-uniswap-v-3-lp-individual-proposal.ts - - kind: ethereum - name: SimpleLoanUniswapV3LPSetProposal - network: sepolia - source: - address: "0x7b48798CE8e95f1412078cF2e1a176CA12839AfA" - abi: SimpleLoanUniswapV3LPSetProposal - startBlock: 8518575 - mapping: - kind: ethereum/events - apiVersion: 0.0.9 - language: wasm/assemblyscript - entities: - - SimpleLoanUniswapV3LPSetProposalProposalMade - abis: - - name: SimpleLoanUniswapV3LPSetProposal - file: ./abis/SimpleLoanUniswapV3LPSetProposal.json - eventHandlers: - - event: ProposalMade(indexed bytes32,indexed - address,(address[],address[],address,address[],bool[],uint256,uint256,uint256,bytes32,uint256,uint24,uint32,uint40,address,bytes,address,bytes32,bool,uint256,uint256,uint256,address)) - handler: handleProposalMade - file: ./src/simple-loan-uniswap-v-3-lp-set-proposal.ts diff --git a/packages/subgraph/tests/.latest.json b/packages/subgraph/tests/.latest.json index a4899dc7..ea8250a5 100644 --- a/packages/subgraph/tests/.latest.json +++ b/packages/subgraph/tests/.latest.json @@ -1,4 +1,4 @@ { "version": "0.6.0", - "timestamp": 1749642846790 + "timestamp": 1749811105822 } \ No newline at end of file From 104280e36bb90fa4819808fbd2c0b5a8bd7116e8 Mon Sep 17 00:00:00 2001 From: microHoffman Date: Fri, 13 Jun 2025 17:41:32 +0200 Subject: [PATCH 12/13] feat: rename Category to AssetCategory --- packages/subgraph/TIME_BASED_DEFAULTS.md | 203 ------------------ packages/subgraph/schema.graphql | 18 +- .../src/multi-token-category-registry.ts | 9 +- packages/subgraph/src/simple-loan.ts | 5 +- packages/subgraph/src/utils.ts | 6 +- packages/subgraph/subgraph.template.yaml | 2 +- .../multi-token-category-registry.test.ts | 10 +- packages/subgraph/tests/simple-loan-utils.ts | 8 +- packages/subgraph/tests/simple-loan.test.ts | 1 + 9 files changed, 33 insertions(+), 229 deletions(-) delete mode 100644 packages/subgraph/TIME_BASED_DEFAULTS.md diff --git a/packages/subgraph/TIME_BASED_DEFAULTS.md b/packages/subgraph/TIME_BASED_DEFAULTS.md deleted file mode 100644 index d298ba80..00000000 --- a/packages/subgraph/TIME_BASED_DEFAULTS.md +++ /dev/null @@ -1,203 +0,0 @@ -# Handling Time-Based Loan Defaults in Subgraphs - -## Problem -Loans default after a certain duration (`createdAt + duration`), but there's no on-chain event emitted when this happens. The subgraph needs a way to mark loans as defaulted based on time calculations. - -## Solutions - -### 1. Schema-Based Approach (Recommended) - -Add a computed field to store the default deadline: - -```graphql -type Loan @entity(immutable: false) { - # ... existing fields ... - defaultDeadline: BigInt! # createdAt + duration - # ... rest of fields ... -} -``` - -**Advantages:** -- Easy to query loans by default status -- Efficient for frontend filtering -- Clear data model - -**Implementation:** -1. Add `defaultDeadline` field to schema -2. Run `npm run codegen` to regenerate types -3. Update `handleLOANCreated` to calculate and store `defaultDeadline` - -### 2. Runtime Status Checking (Current Implementation) - -Use helper functions to check loan status based on current time: - -```typescript -function isLoanDefaulted(loan: Loan, currentTimestamp: BigInt): boolean { - if (loan.status != "Active") return false; - const defaultDeadline = loan.createdAt.plus(loan.duration); - return currentTimestamp.gt(defaultDeadline); -} -``` - -**Advantages:** -- No schema changes required -- Works immediately -- Can be applied to existing loans - -**Disadvantages:** -- Requires checking on every query -- More complex GraphQL queries needed - -### 3. Event-Driven Updates - -Update loan statuses whenever any related event occurs: - -```typescript -export function handleLOANClaimed(event: LOANClaimed): void { - // ... existing logic ... - - // Always check for time-based defaults - updateLoanStatusIfDefaulted(loan, event.block.timestamp); - loan.save(); -} -``` - -### 4. Query-Time Filtering - -Use GraphQL queries that filter based on calculated values: - -```graphql -query GetDefaultedLoans($currentTime: BigInt!) { - loans( - where: { - status: "Active" - # This would need to be calculated client-side or with a custom resolver - } - ) { - id - createdAt - duration - status - } -} -``` - -## Frontend Usage Examples - -### 1. Query with Status Calculation - -```typescript -const GET_LOANS_WITH_STATUS = gql` - query GetLoans { - loans { - id - createdAt - duration - status - defaultDeadline # If using schema approach - } - } -`; - -// Client-side calculation -const loansWithCalculatedStatus = loans.map(loan => ({ - ...loan, - isDefaulted: loan.status === 'Active' && - Date.now() / 1000 > (loan.createdAt + loan.duration), - effectiveStatus: loan.status === 'Active' && - Date.now() / 1000 > (loan.createdAt + loan.duration) - ? 'Defaulted' : loan.status -})); -``` - -### 2. Filter Defaulted Loans - -```typescript -// If using defaultDeadline field -const GET_DEFAULTED_LOANS = gql` - query GetDefaultedLoans($currentTime: BigInt!) { - loans( - where: { - or: [ - { status: "Defaulted" }, - { - status: "Active", - defaultDeadline_lt: $currentTime - } - ] - } - ) { - id - status - defaultDeadline - } - } -`; -``` - -## Implementation Steps - -1. **Choose Your Approach:** - - For new projects: Use Schema-Based Approach (#1) - - For existing projects: Use Runtime Status Checking (#2) - -2. **Update Schema (if using approach #1):** - ```bash - # Add defaultDeadline field to schema.graphql - npm run codegen - ``` - -3. **Update Event Handlers:** - - Implement time-based status checking - - Update `handleLOANCreated`, `handleLOANClaimed`, etc. - -4. **Frontend Integration:** - - Update queries to handle time-based defaults - - Add client-side status calculation if needed - -## Best Practices - -1. **Consistency:** Always check for time-based defaults in all loan-related event handlers -2. **Performance:** Use schema fields for frequently queried data -3. **Accuracy:** Consider block timestamps vs real-world time -4. **Extensions:** Handle loan extensions by updating duration/defaultDeadline -5. **Testing:** Test with various time scenarios - -## Alternative Solutions - -### Custom Resolver (Advanced) -Create a custom resolver that calculates status dynamically: - -```typescript -// This would require extending the subgraph with custom logic -export function resolveLoanStatus(loan: Loan, args: any, context: any): string { - if (loan.status !== "Active") return loan.status; - - const currentTime = context.block.timestamp; - const defaultDeadline = loan.createdAt.plus(loan.duration); - - return currentTime.gt(defaultDeadline) ? "Defaulted" : "Active"; -} -``` - -### Periodic Update Job -Create a separate service that periodically updates loan statuses: - -```typescript -// External service (not in subgraph) -async function updateDefaultedLoans() { - const activeLoans = await getActiveLoans(); - const currentTime = Math.floor(Date.now() / 1000); - - for (const loan of activeLoans) { - if (currentTime > loan.createdAt + loan.duration) { - // Update loan status in subgraph or database - await markLoanAsDefaulted(loan.id); - } - } -} -``` - -## Conclusion - -The **Schema-Based Approach** with `defaultDeadline` field is recommended for most cases as it provides the best balance of performance, clarity, and functionality. The current implementation with runtime checking works well as a transitional solution. \ No newline at end of file diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 3ea5202a..dcfed86a 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -5,14 +5,14 @@ type Account @entity(immutable: true) { loansAsLoanOwner: [Loan!]! @derivedFrom(field: "loanOwner") } -type Category @entity(immutable: true) { +type AssetCategory @entity(immutable: true) { id: Bytes! # category id assets: [AssetContract!]! @derivedFrom(field: "category") } type AssetContract @entity(immutable: true) { id: Bytes! # asset address - category: Category + category: AssetCategory # TODO add also metadata like name / symbol / decimals? } @@ -30,11 +30,16 @@ type Asset @entity(immutable: true) { enum LoanStatus { Active Repaid - # TODO this state will probably never be reached right? - Defaulted + # we do not use defaulted state here as it can't be calculated from the onchain event + # as there is no onchain event when a loan defaults + # Defaulted Claimed } +enum LoanType { + SimpleLoan +} + type Loan @entity(immutable: false) { # Combination of chainId and loanId from contract id: Bytes! # {loanTokenAddress}{loanId} @@ -52,7 +57,6 @@ type Loan @entity(immutable: false) { repaidAt: BigInt claimedAt: BigInt - # Loan contract address contractAddress: Bytes! refinancingLoanId: BigInt! @@ -91,6 +95,8 @@ type Loan @entity(immutable: false) { hasDefaulted: Boolean! + loanType: LoanType! + # TODO also add Loan contract version? } @@ -462,7 +468,7 @@ type ChainlinkFeed @entity(immutable: true) { aggregator: Bytes! # feed address } -type LOANExtended @entity(immutable: true) { +type LoanExtendedEvent @entity(immutable: true) { id: Bytes! loanId: BigInt! # uint256 originalDefaultTimestamp: BigInt! # uint40 diff --git a/packages/subgraph/src/multi-token-category-registry.ts b/packages/subgraph/src/multi-token-category-registry.ts index 92896e5c..3ddf7139 100644 --- a/packages/subgraph/src/multi-token-category-registry.ts +++ b/packages/subgraph/src/multi-token-category-registry.ts @@ -4,16 +4,15 @@ import { } from "../generated/MultiTokenCategoryRegistry/MultiTokenCategoryRegistry" import { AssetContract, - Category, + AssetCategory, } from "../generated/schema" -import { store } from '@graphprotocol/graph-ts' -import { Bytes, Address } from "@graphprotocol/graph-ts" +import { Bytes } from "@graphprotocol/graph-ts" export function handleCategoryRegistered(event: CategoryRegisteredEvent): void { const categoryId = Bytes.fromI32(event.params.category) - let category = Category.load(categoryId) + let category = AssetCategory.load(categoryId) if (category == null) { - category = new Category(categoryId) + category = new AssetCategory(categoryId) category.save() } let assetContract = AssetContract.load(event.params.assetAddress) diff --git a/packages/subgraph/src/simple-loan.ts b/packages/subgraph/src/simple-loan.ts index bedfe4fc..97eda15d 100644 --- a/packages/subgraph/src/simple-loan.ts +++ b/packages/subgraph/src/simple-loan.ts @@ -20,7 +20,7 @@ export function getLoanId(loanContractAddress: Address, loanId: BigInt): Bytes { return loanContractAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(loanId))) } -export function handleLOANCreated(event: LOANCreatedEvent): Loan { +export function handleLOANCreated(event: LOANCreatedEvent): void { const loanId = getLoanId(event.address, event.params.loanId) const loan = new Loan(loanId) loan.loanId = event.params.loanId @@ -32,6 +32,7 @@ export function handleLOANCreated(event: LOANCreatedEvent): Loan { loan.loanOwner = getOrCreateAccount(event.params.terms.lender).id loan.borrower = getOrCreateAccount(event.params.terms.borrower).id loan.duration = event.params.terms.duration + loan.loanType = "SimpleLoan" log.info("loan.duration", []) @@ -74,8 +75,6 @@ export function handleLOANCreated(event: LOANCreatedEvent): Loan { loan.hasDefaulted = false loan.save() - - return loan } export function handleLOANPaidBack(event: LOANPaidBackEvent): void { diff --git a/packages/subgraph/src/utils.ts b/packages/subgraph/src/utils.ts index 9b80e17d..8deebe50 100644 --- a/packages/subgraph/src/utils.ts +++ b/packages/subgraph/src/utils.ts @@ -1,4 +1,4 @@ -import { Asset, AssetContract, Category, Account } from "../generated/schema" +import { Asset, AssetContract, AssetCategory, Account } from "../generated/schema" import { Bytes, BigInt, Address } from "@graphprotocol/graph-ts" // Helper function to create or get Asset entity @@ -10,9 +10,9 @@ export function getOrCreateAsset(contractAddress: Bytes, tokenId: BigInt, catego let assetContract = AssetContract.load(contractAddress) if (assetContract == null) { // Create or get the category - let categoryEntity = Category.load(Bytes.fromI32(category)) + let categoryEntity = AssetCategory.load(Bytes.fromI32(category)) if (categoryEntity == null) { - categoryEntity = new Category(Bytes.fromI32(category)) + categoryEntity = new AssetCategory(Bytes.fromI32(category)) categoryEntity.save() } diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index 999d19e4..c9632f6e 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -300,7 +300,7 @@ dataSources: language: wasm/assemblyscript entities: - AssetInCategory - - Category + - AssetCategory #- CategoryRegistered #- CategoryUnregistered #- MultiTokenCategoryRegistryOwnershipTransferStarted diff --git a/packages/subgraph/tests/multi-token-category-registry.test.ts b/packages/subgraph/tests/multi-token-category-registry.test.ts index 3acde73b..f5d3ad05 100644 --- a/packages/subgraph/tests/multi-token-category-registry.test.ts +++ b/packages/subgraph/tests/multi-token-category-registry.test.ts @@ -17,7 +17,7 @@ describe("MultiTokenCategoryRegistry Events", () => { clearStore() }) - test("handleCategoryRegistered - creates a new Category entity", () => { + test("handleCategoryRegistered - creates a new AssetCategory entity", () => { let category = Bytes.fromHexString("0x1234").toI32() let assetAddress = Address.fromString("0x0000000000000000000000000000000000000001") @@ -27,9 +27,9 @@ describe("MultiTokenCategoryRegistry Events", () => { let categoryId = Bytes.fromI32(category).toHexString() - assert.entityCount("Category", 1) + assert.entityCount("AssetCategory", 1) assert.fieldEquals( - "Category", + "AssetCategory", categoryId, "id", categoryId @@ -50,7 +50,7 @@ describe("MultiTokenCategoryRegistry Events", () => { ) }) - test("handleCategoryUnregistered - removes the Category entity", () => { + test("handleCategoryUnregistered - removes the AssetCategory entity", () => { let category = Bytes.fromHexString("0x1234").toI32() let registryAddress = Address.fromString("0x0000000000000000000000000000000000000001") @@ -62,7 +62,7 @@ describe("MultiTokenCategoryRegistry Events", () => { let unregisterEvent = createCategoryUnregisteredEvent(registryAddress) handleCategoryUnregistered(unregisterEvent) - assert.entityCount("Category", 1) + assert.entityCount("AssetCategory", 1) assert.entityCount("AssetContract", 1) const assetContract = AssetContract.load(Bytes.fromHexString(registryAddress.toHexString())) assert.assertNotNull(assetContract) diff --git a/packages/subgraph/tests/simple-loan-utils.ts b/packages/subgraph/tests/simple-loan-utils.ts index c8de27d2..612194c9 100644 --- a/packages/subgraph/tests/simple-loan-utils.ts +++ b/packages/subgraph/tests/simple-loan-utils.ts @@ -1,7 +1,7 @@ import { Address, BigInt, ethereum, Bytes } from "@graphprotocol/graph-ts" import { LOANCreated, LOANPaidBack, LOANClaimed, LOANExtended, ExtensionProposalMade } from "../generated/SimpleLoan/SimpleLoan" import { assert, test, newMockEvent, dataSourceMock, createMockedFunction } from 'matchstick-as/assembly/index' -import { handleLOANCreated } from "../src/simple-loan" +import { getLoanId, handleLOANCreated } from "../src/simple-loan" import { Loan } from "../generated/schema"; // Define a class to hold the parameters @@ -29,6 +29,7 @@ export class TestLoanParams { extra: Bytes = Bytes.fromHexString("0x1234"); loanTokenAddress: Address = Address.fromString("0x0000000000000000000000000000000000000006"); loanContractAddress: Address = Address.fromString("0x0000000000000000000000000000000000000007"); + loanType: string = "SimpleLoan"; } export function createTestLoan(loanId: BigInt, params: TestLoanParams | null = null): Loan { @@ -58,13 +59,14 @@ export function createTestLoan(loanId: BigInt, params: TestLoanParams | null = n p.borrowerSpecHash, p.sourceOfFunds, p.extra, - p.loanContractAddress + p.loanContractAddress, ); createMockedFunction(p.loanContractAddress, 'loanToken', 'loanToken():(address)') .returns([ethereum.Value.fromAddress(p.loanTokenAddress)]) - const loan = handleLOANCreated(createEvent); + handleLOANCreated(createEvent); + const loan = new Loan(getLoanId(p.loanContractAddress, loanId)); return loan; } diff --git a/packages/subgraph/tests/simple-loan.test.ts b/packages/subgraph/tests/simple-loan.test.ts index a5b2967d..427e5391 100644 --- a/packages/subgraph/tests/simple-loan.test.ts +++ b/packages/subgraph/tests/simple-loan.test.ts @@ -40,6 +40,7 @@ describe("SimpleLoan", () => { assert.fieldEquals("Loan", loanEntityId, "createdAt", params.createdAt.toString()) assert.fieldEquals("Loan", loanEntityId, "status", "Active") assert.fieldEquals("Loan", loanEntityId, "loanTokenAddress", loanTokenAddress.toHexString()) + assert.fieldEquals("Loan", loanEntityId, "loanType", "SimpleLoan") }) test("handleLOANPaidBack - updates Loan status to Repaid", () => { From 8079aa6e5ef0ddf58ebbf4bb2b4da579e79251c4 Mon Sep 17 00:00:00 2001 From: microHoffman Date: Fri, 13 Jun 2025 17:53:32 +0200 Subject: [PATCH 13/13] feat: add LoanExtendedEvent entity, fix casing --- packages/subgraph/schema.graphql | 86 +++++++++---------- packages/subgraph/src/hub.ts | 4 +- .../simple-loan-elastic-chainlink-proposal.ts | 11 --- packages/subgraph/src/simple-loan.ts | 29 +------ packages/subgraph/subgraph.template.yaml | 4 +- packages/subgraph/tests/hub.test.ts | 8 +- packages/subgraph/tests/loan-token.test.ts | 7 -- packages/subgraph/tests/simple-loan.test.ts | 8 +- 8 files changed, 59 insertions(+), 98 deletions(-) diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index dcfed86a..42b5d8ab 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -489,7 +489,7 @@ type LoanTokenTransfer @entity(immutable: true) { transactionHash: Bytes! } -type TagSet @entity(immutable: true) { +type TagSetEvent @entity(immutable: true) { id: Bytes! _address: Bytes! # address tag: Bytes! # bytes32 @@ -503,50 +503,50 @@ type TagSet @entity(immutable: true) { # TO REMOVE??? # ============================== -type LOANPaidBack @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} +# type LoanPaidBackEvent @entity(immutable: true) { +# id: Bytes! +# loanId: BigInt! # uint256 +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } -type LOANClaimed @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - defaulted: Boolean! # bool - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} +# type LoanClaimedEvent @entity(immutable: true) { +# id: Bytes! +# loanId: BigInt! # uint256 +# defaulted: Boolean! # bool +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } -type LOANCreated @entity(immutable: true) { - id: Bytes! - loanId: BigInt! # uint256 - proposalHash: Bytes! # bytes32 - proposalContract: Bytes! # address - refinancingLoanId: BigInt! # uint256 - terms_lender: Bytes! # address - terms_borrower: Bytes! # address - terms_duration: BigInt! # uint32 - terms_collateral_category: Int! # uint8 - terms_collateral_assetAddress: Bytes! # address - terms_collateral_id: BigInt! # uint256 - terms_collateral_amount: BigInt! # uint256 - terms_credit_category: Int! # uint8 - terms_credit_assetAddress: Bytes! # address - terms_credit_id: BigInt! # uint256 - terms_credit_amount: BigInt! # uint256 - terms_fixedInterestAmount: BigInt! # uint256 - terms_accruingInterestAPR: Int! # uint24 - terms_lenderSpecHash: Bytes! # bytes32 - terms_borrowerSpecHash: Bytes! # bytes32 - lenderSpec_sourceOfFunds: Bytes! # address - extra: Bytes! # bytes - blockNumber: BigInt! - blockTimestamp: BigInt! - transactionHash: Bytes! -} +# type LoanCreatedEvent @entity(immutable: true) { +# id: Bytes! +# loanId: BigInt! # uint256 +# proposalHash: Bytes! # bytes32 +# proposalContract: Bytes! # address +# refinancingLoanId: BigInt! # uint256 +# terms_lender: Bytes! # address +# terms_borrower: Bytes! # address +# terms_duration: BigInt! # uint32 +# terms_collateral_category: Int! # uint8 +# terms_collateral_assetAddress: Bytes! # address +# terms_collateral_id: BigInt! # uint256 +# terms_collateral_amount: BigInt! # uint256 +# terms_credit_category: Int! # uint8 +# terms_credit_assetAddress: Bytes! # address +# terms_credit_id: BigInt! # uint256 +# terms_credit_amount: BigInt! # uint256 +# terms_fixedInterestAmount: BigInt! # uint256 +# terms_accruingInterestAPR: Int! # uint24 +# terms_lenderSpecHash: Bytes! # bytes32 +# terms_borrowerSpecHash: Bytes! # bytes32 +# lenderSpec_sourceOfFunds: Bytes! # address +# extra: Bytes! # bytes +# blockNumber: BigInt! +# blockTimestamp: BigInt! +# transactionHash: Bytes! +# } # =============================== # UNUSED ENTITIES diff --git a/packages/subgraph/src/hub.ts b/packages/subgraph/src/hub.ts index 3f305f04..6374ebd6 100644 --- a/packages/subgraph/src/hub.ts +++ b/packages/subgraph/src/hub.ts @@ -2,11 +2,11 @@ import { TagSet as TagSetEvent, } from "../generated/Hub/Hub" import { - TagSet, + TagSetEvent as TagSetEventEntity, } from "../generated/schema" export function handleTagSet(event: TagSetEvent): void { - const entity = new TagSet( + const entity = new TagSetEventEntity( event.transaction.hash.concatI32(event.logIndex.toI32()), ) entity._address = event.params._address diff --git a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts index 2acb6e2a..9a836dfe 100644 --- a/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts +++ b/packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts @@ -5,27 +5,20 @@ import { Bytes, BigInt } from "@graphprotocol/graph-ts" import { log } from "@graphprotocol/graph-ts" export function handleProposalMade(event: ProposalMadeEvent): void { - log.info("aaaaaaaaaaaaaaaaaaa: {}", [event.params.proposalHash.toHexString()]) // Create the specific event entity const eventEntity = new SimpleLoanElasticChainlinkProposalProposalMade( event.transaction.hash.concatI32(event.logIndex.toI32()), ) eventEntity.proposalHash = event.params.proposalHash - log.info("bbbbbbbbbbbbbbbbbbbb: {}", [event.params.proposer.toString()]) - log.info("bbbbbbbbbbbbbbbbasddbbbb: {}", [event.params.proposal.proposer.toString()]) eventEntity.proposer = event.params.proposer eventEntity.collateralCategory = event.params.proposal.collateralCategory - log.info("xx: {}", [event.params.proposal.collateralAddress.toHexString()]) eventEntity.collateralAddress = event.params.proposal.collateralAddress eventEntity.collateralId = event.params.proposal.collateralId eventEntity.checkCollateralStateFingerprint = event.params.proposal.checkCollateralStateFingerprint eventEntity.collateralStateFingerprint = event.params.proposal.collateralStateFingerprint - log.info("dddddddddddddddddd: {}", [event.params.proposal.creditAddress.toHexString()]) eventEntity.creditAddress = event.params.proposal.creditAddress - log.info("xczxczxcc", []) - // log.info("eeeeeeeeeeeeeeeeee: {}", [event.params.proposal.feedIntermediaryDenominations[0].toString()]) eventEntity.feedIntermediaryDenominations = changetype( event.params.proposal.feedIntermediaryDenominations, ) @@ -34,7 +27,6 @@ export function handleProposalMade(event: ProposalMadeEvent): void { eventEntity.minCreditAmount = event.params.proposal.minCreditAmount eventEntity.availableCreditLimit = event.params.proposal.availableCreditLimit - log.info("fffffffffffffffffff: {}", [event.params.proposal.utilizedCreditId.toString()]) eventEntity.utilizedCreditId = event.params.proposal.utilizedCreditId eventEntity.fixedInterestAmount = event.params.proposal.fixedInterestAmount @@ -42,16 +34,13 @@ export function handleProposalMade(event: ProposalMadeEvent): void { event.params.proposal.accruingInterestAPR eventEntity.durationOrDate = event.params.proposal.durationOrDate eventEntity.expiration = event.params.proposal.expiration - log.info("gggggggggggggggggggg: {}", [event.params.proposal.allowedAcceptor.toString()]) eventEntity.allowedAcceptor = event.params.proposal.allowedAcceptor - log.info("hhhhhhhhhhhhhhhhhhh: {}", [event.params.proposal.proposer.toString()]) eventEntity.proposer = event.params.proposal.proposer eventEntity.proposerSpecHash = event.params.proposal.proposerSpecHash eventEntity.isOffer = event.params.proposal.isOffer eventEntity.refinancingLoanId = event.params.proposal.refinancingLoanId eventEntity.nonceSpace = event.params.proposal.nonceSpace eventEntity.nonce = event.params.proposal.nonce - log.info("iiiiiiiiiiiiiiiiiiii: {}", [event.params.proposal.loanContract.toString()]) eventEntity.loanContract = event.params.proposal.loanContract eventEntity.blockNumber = event.block.number diff --git a/packages/subgraph/src/simple-loan.ts b/packages/subgraph/src/simple-loan.ts index 97eda15d..bb151550 100644 --- a/packages/subgraph/src/simple-loan.ts +++ b/packages/subgraph/src/simple-loan.ts @@ -9,7 +9,7 @@ import { } from "../generated/SimpleLoan/SimpleLoan" import { ExtensionProposal, - LOANExtended, + LoanExtendedEvent as LoanExtendedEventEntity, Loan, } from "../generated/schema" import { getOrCreateAccount } from "./helpers" @@ -33,47 +33,22 @@ export function handleLOANCreated(event: LOANCreatedEvent): void { loan.borrower = getOrCreateAccount(event.params.terms.borrower).id loan.duration = event.params.terms.duration loan.loanType = "SimpleLoan" - - log.info("loan.duration", []) - loan.createdAt = event.block.timestamp - loan.collateral = getOrCreateAsset(event.params.terms.collateral.assetAddress, event.params.terms.collateral.id, event.params.terms.collateral.category).id loan.collateralAmount = event.params.terms.collateral.amount - - log.info("loan.collateralAmount", []) - loan.credit = getOrCreateAsset(event.params.terms.credit.assetAddress, event.params.terms.credit.id, event.params.terms.credit.category).id loan.creditAmount = event.params.terms.credit.amount - - log.info("loan.collateral", []) - loan.status = "Active" - loan.fixedInterestAmount = event.params.terms.fixedInterestAmount loan.accruingInterestAPR = event.params.terms.accruingInterestAPR - - log.info("loan.accruingInterestAPR", []) - loan.lenderSpecHash = event.params.terms.lenderSpecHash loan.borrowerSpecHash = event.params.terms.borrowerSpecHash - - log.info("loan.sourceOfFunds", []) loan.sourceOfFunds = event.params.lenderSpec.sourceOfFunds - - log.info("loan.aasda", []) - loan.defaultDate = event.params.terms.duration.plus(loan.createdAt) - loan.extra = event.params.extra - - log.info("before contract call", []) - const simpleLoanContract = SimpleLoan.bind(Address.fromBytes(loan.contractAddress)) loan.loanTokenAddress = simpleLoanContract.loanToken() - loan.hasDefaulted = false - loan.save() } @@ -123,7 +98,7 @@ export function handleLOANExtended(event: LOANExtendedEvent): void { loan.save() // save the event as well - const entity = new LOANExtended( + const entity = new LoanExtendedEventEntity( event.transaction.hash.concatI32(event.logIndex.toI32()), ) entity.loanId = event.params.loanId diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index c9632f6e..514711ce 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -108,7 +108,7 @@ dataSources: - ExtensionProposalMade - LOANClaimed - LOANCreated - - LOANExtended + - LoanExtendedEvent - LOANPaidBack #- PoolSupply #- PoolWithdraw @@ -241,7 +241,7 @@ dataSources: entities: #- OwnershipTransferStarted #- OwnershipTransferred - - TagSet + - TagSetEvent abis: - name: Hub file: ./abis/Hub.json diff --git a/packages/subgraph/tests/hub.test.ts b/packages/subgraph/tests/hub.test.ts index 10bb7bc8..23fafd98 100644 --- a/packages/subgraph/tests/hub.test.ts +++ b/packages/subgraph/tests/hub.test.ts @@ -25,21 +25,21 @@ describe("Hub Events", () => { const tagSetId: Bytes = event.transaction.hash.concatI32(event.logIndex.toI32()) - assert.entityCount("TagSet", 1) + assert.entityCount("TagSetEvent", 1) assert.fieldEquals( - "TagSet", + "TagSetEvent", tagSetId.toHexString(), "tag", tag.toHexString() ) assert.fieldEquals( - "TagSet", + "TagSetEvent", tagSetId.toHexString(), "hasTag", value.toString(), ) assert.fieldEquals( - "TagSet", + "TagSetEvent", tagSetId.toHexString(), "_address", contractAddress.toHexString() diff --git a/packages/subgraph/tests/loan-token.test.ts b/packages/subgraph/tests/loan-token.test.ts index 34149992..e8aa3e4b 100644 --- a/packages/subgraph/tests/loan-token.test.ts +++ b/packages/subgraph/tests/loan-token.test.ts @@ -33,25 +33,18 @@ describe("LoanToken Events", () => { loanParams.lender = from loanParams.loanContractAddress = loanContractAddress - log.info("before createTestLoan", []) createTestLoan(tokenId, loanParams) - log.info("after createTestLoan", []) assert.fieldEquals("Loan", loanId.toHexString(), "loanOwner", from.toHexString()) - log.info("before createTransferEvent", []) let event = createTransferEvent(from, to, tokenId, loanTokenAddress) - log.info("after createTransferEvent", []) const transferEventId = event.transaction.hash.concatI32(event.logIndex.toI32()) createMockedFunction(loanTokenAddress, 'loanContract', 'loanContract(uint256):(address)') .withArgs([ethereum.Value.fromUnsignedBigInt(event.params.tokenId)]) .returns([ethereum.Value.fromAddress(loanContractAddress)]) - log.info("before handleTransfer", []) handleTransfer(event) - log.info("after handleTransfer", []) - assert.fieldEquals("Loan", loanId.toHexString(), "loanOwner", to.toHexString()) assert.entityCount("LoanTokenTransfer", 1) diff --git a/packages/subgraph/tests/simple-loan.test.ts b/packages/subgraph/tests/simple-loan.test.ts index 427e5391..021baea4 100644 --- a/packages/subgraph/tests/simple-loan.test.ts +++ b/packages/subgraph/tests/simple-loan.test.ts @@ -79,8 +79,6 @@ describe("SimpleLoan", () => { handleLOANClaimed(claimEvent) const loanEntityId = getLoanId(params.loanContractAddress, loanId).toHexString() - log.info("loanEntityId: {}", [loanEntityId]) - log.info("params.loanContractAddress: {}", [params.loanContractAddress.toHexString()]) assert.fieldEquals("Loan", loanEntityId, "status", "Claimed") assert.fieldEquals("Loan", loanEntityId, "hasDefaulted", defaulted.toString()) @@ -112,6 +110,12 @@ describe("SimpleLoan", () => { const loanEntityId = getLoanId(loanContractAddress, loanId).toHexString() assert.fieldEquals("Loan", loanEntityId, "defaultDate", extendedDefaultTimestamp.toString()) + + assert.entityCount("LoanExtendedEvent", 1) + const eventId = extendEvent.transaction.hash.concatI32(extendEvent.logIndex.toI32()) + assert.fieldEquals("LoanExtendedEvent", eventId.toHexString(), "loanId", loanId.toString()) + assert.fieldEquals("LoanExtendedEvent", eventId.toHexString(), "originalDefaultTimestamp", originalDefaultTimestamp.toString()) + assert.fieldEquals("LoanExtendedEvent", eventId.toHexString(), "extendedDefaultTimestamp", extendedDefaultTimestamp.toString()) }) test("handleExtensionProposalMade - creates a new ExtensionProposal entity", () => {