@ensuro/core 2.0.0-beta8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +31 -14
  2. package/build/contracts/AccessManager.sol/AccessManager.json +7 -2
  3. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +28 -3
  4. package/build/contracts/EToken.sol/EToken.json +21 -15
  5. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +21 -2
  6. package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +26 -1
  7. package/build/contracts/Policy.sol/Policy.json +2 -2
  8. package/build/contracts/PolicyPool.sol/PolicyPool.json +40 -2
  9. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +19 -0
  10. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +21 -15
  11. package/build/contracts/Reserve.sol/Reserve.json +19 -13
  12. package/build/contracts/RiskModule.sol/RiskModule.json +19 -0
  13. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +1110 -0
  14. package/build/contracts/TimeScaled.sol/TimeScaled.json +3 -17
  15. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +137 -2
  16. package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
  17. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +26 -1
  18. package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +38 -0
  19. package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +19 -0
  20. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  21. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
  22. package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +180 -0
  23. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +28 -2
  24. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +21 -2
  25. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +115 -2
  26. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  27. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +111 -2
  28. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
  29. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
  30. package/contracts/AccessManager.sol +31 -2
  31. package/contracts/ERC4626AssetManager.sol +8 -2
  32. package/contracts/EToken.sol +129 -60
  33. package/contracts/LPManualWhitelist.sol +18 -2
  34. package/contracts/LiquidityThresholdAssetManager.sol +28 -12
  35. package/contracts/Policy.sol +5 -3
  36. package/contracts/PolicyPool.sol +221 -29
  37. package/contracts/PolicyPoolComponent.sol +36 -25
  38. package/contracts/PremiumsAccount.sol +220 -32
  39. package/contracts/Reserve.sol +130 -19
  40. package/contracts/RiskModule.sol +53 -20
  41. package/contracts/SignedQuoteRiskModule.sol +310 -0
  42. package/contracts/TimeScaled.sol +19 -15
  43. package/contracts/TrustfulRiskModule.sol +107 -6
  44. package/contracts/dependencies/WadRayMath.sol +126 -0
  45. package/contracts/interfaces/IAccessManager.sol +68 -13
  46. package/contracts/interfaces/IAssetManager.sol +69 -2
  47. package/contracts/interfaces/IEToken.sol +4 -1
  48. package/contracts/interfaces/ILPWhitelist.sol +17 -0
  49. package/contracts/interfaces/IPolicyPool.sol +19 -1
  50. package/contracts/interfaces/IPolicyPoolComponent.sol +5 -1
  51. package/contracts/interfaces/IRiskModule.sol +67 -4
  52. package/contracts/mocks/InterfaceIdCalculator.sol +32 -0
  53. package/contracts/mocks/PolicyHolderMock.sol +21 -0
  54. package/contracts/mocks/PolicyPoolComponentMock.sol +10 -0
  55. package/contracts/mocks/PolicyPoolMock.sol +31 -0
  56. package/contracts/mocks/RiskModuleMock.sol +7 -1
  57. package/js/deploy.js +734 -0
  58. package/js/test-utils.js +184 -69
  59. package/package.json +4 -2
  60. package/scripts/change-pragma.sh +19 -0
  61. package/scripts/deploySmokeTest-fork.sh +53 -0
  62. package/scripts/deploySmokeTest.sh +51 -0
  63. package/scripts/storageLayout.js +33 -0
  64. package/scripts/utils.sh +65 -0
  65. package/contracts/WadRayMath.sol +0 -135
@@ -381,8 +381,8 @@
381
381
  "type": "function"
382
382
  }
383
383
  ],
384
- "bytecode": "0x60806040523480156200001157600080fd5b506040516200169a3803806200169a8339810160408190526200003491620001de565b8151829082906200004d90600090602085019062000081565b5080516200006390600190602084019062000081565b5050600680546001600160a01b03191633179055506200029b915050565b8280546200008f9062000248565b90600052602060002090601f016020900481019282620000b35760008555620000fe565b82601f10620000ce57805160ff1916838001178555620000fe565b82800160010185558215620000fe579182015b82811115620000fe578251825591602001919060010190620000e1565b506200010c92915062000110565b5090565b5b808211156200010c576000815560010162000111565b600082601f8301126200013957600080fd5b81516001600160401b038082111562000156576200015662000285565b604051601f8301601f19908116603f0116810190828211818310171562000181576200018162000285565b816040528381526020925086838588010111156200019e57600080fd5b600091505b83821015620001c25785820183015181830184015290820190620001a3565b83821115620001d45760008385830101525b9695505050505050565b60008060408385031215620001f257600080fd5b82516001600160401b03808211156200020a57600080fd5b620002188683870162000127565b935060208501519150808211156200022f57600080fd5b506200023e8582860162000127565b9150509250929050565b600181811c908216806200025d57607f821691505b602082108114156200027f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6113ef80620002ab6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806342966c6811610097578063a22cb46511610066578063a22cb465146101ff578063b88d4fde14610212578063c87b56dd14610225578063e985e9c51461023857600080fd5b806342966c68146101b05780636352211e146101c357806370a08231146101d657806395d89b41146101f757600080fd5b8063095ea7b3116100d3578063095ea7b31461016257806323b872dd1461017757806340c10f191461018a57806342842e0e1461019d57600080fd5b806301ffc9a7146100fa57806306fdde0314610122578063081812fc14610137575b600080fd5b61010d6101083660046110d4565b610274565b60405190151581526020015b60405180910390f35b61012a6102c6565b60405161011991906111bf565b61014a61014536600461110e565b610358565b6040516001600160a01b039091168152602001610119565b6101756101703660046110aa565b61037f565b005b610175610185366004610f56565b61049a565b6101756101983660046110aa565b6104cb565b6101756101ab366004610f56565b6104d9565b6101756101be36600461110e565b6104f4565b61014a6101d136600461110e565b61056e565b6101e96101e4366004610f08565b6105ce565b604051908152602001610119565b61012a610654565b61017561020d36600461106e565b610663565b610175610220366004610f92565b61066e565b61012a61023336600461110e565b6106a6565b61010d610246366004610f23565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b14806102a557506001600160e01b03198216635b5e139f60e01b145b806102c057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102d5906112e1565b80601f0160208091040260200160405190810160405280929190818152602001828054610301906112e1565b801561034e5780601f106103235761010080835404028352916020019161034e565b820191906000526020600020905b81548152906001019060200180831161033157829003601f168201915b5050505050905090565b60006103638261071a565b506000908152600460205260409020546001600160a01b031690565b600061038a8261056e565b9050806001600160a01b0316836001600160a01b031614156103fd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061041957506104198133610246565b61048b5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016103f4565b6104958383610779565b505050565b6104a433826107e7565b6104c05760405162461bcd60e51b81526004016103f490611224565b610495838383610866565b6104d58282610a02565b5050565b6104958383836040518060200160405280600081525061066e565b336104fe8261056e565b6001600160a01b0316146105625760405162461bcd60e51b815260206004820152602560248201527f4552433732313a206275726e206f6620746f6b656e2074686174206973206e6f6044820152643a1037bbb760d91b60648201526084016103f4565b61056b81610b44565b50565b6000818152600260205260408120546001600160a01b0316806102c05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103f4565b60006001600160a01b0382166106385760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103f4565b506001600160a01b031660009081526003602052604090205490565b6060600180546102d5906112e1565b6104d5338383610bdf565b61067833836107e7565b6106945760405162461bcd60e51b81526004016103f490611224565b6106a084848484610cae565b50505050565b60606106b18261071a565b60006106c860408051602081019091526000815290565b905060008151116106e85760405180602001604052806000815250610713565b806106f284610ce1565b604051602001610703929190611153565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b031661056b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103f4565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906107ae8261056e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806107f38361056e565b9050806001600160a01b0316846001600160a01b0316148061083a57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b8061085e5750836001600160a01b031661085384610358565b6001600160a01b0316145b949350505050565b826001600160a01b03166108798261056e565b6001600160a01b0316146108dd5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016103f4565b6001600160a01b03821661093f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103f4565b61094a600082610779565b6001600160a01b038316600090815260036020526040812080546001929061097390849061129e565b90915550506001600160a01b03821660009081526003602052604081208054600192906109a1908490611272565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038216610a585760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103f4565b6000818152600260205260409020546001600160a01b031615610abd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103f4565b6001600160a01b0382166000908152600360205260408120805460019290610ae6908490611272565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610b4f8261056e565b9050610b5c600083610779565b6001600160a01b0381166000908152600360205260408120805460019290610b8590849061129e565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b816001600160a01b0316836001600160a01b03161415610c415760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103f4565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610cb9848484610866565b610cc584848484610ddf565b6106a05760405162461bcd60e51b81526004016103f4906111d2565b606081610d055750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610d2f5780610d198161131c565b9150610d289050600a8361128a565b9150610d09565b60008167ffffffffffffffff811115610d4a57610d4a61138d565b6040519080825280601f01601f191660200182016040528015610d74576020820181803683370190505b5090505b841561085e57610d8960018361129e565b9150610d96600a86611337565b610da1906030611272565b60f81b818381518110610db657610db6611377565b60200101906001600160f81b031916908160001a905350610dd8600a8661128a565b9450610d78565b60006001600160a01b0384163b15610ee157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610e23903390899088908890600401611182565b602060405180830381600087803b158015610e3d57600080fd5b505af1925050508015610e6d575060408051601f3d908101601f19168201909252610e6a918101906110f1565b60015b610ec7573d808015610e9b576040519150601f19603f3d011682016040523d82523d6000602084013e610ea0565b606091505b508051610ebf5760405162461bcd60e51b81526004016103f4906111d2565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061085e565b506001949350505050565b80356001600160a01b0381168114610f0357600080fd5b919050565b600060208284031215610f1a57600080fd5b61071382610eec565b60008060408385031215610f3657600080fd5b610f3f83610eec565b9150610f4d60208401610eec565b90509250929050565b600080600060608486031215610f6b57600080fd5b610f7484610eec565b9250610f8260208501610eec565b9150604084013590509250925092565b60008060008060808587031215610fa857600080fd5b610fb185610eec565b9350610fbf60208601610eec565b925060408501359150606085013567ffffffffffffffff80821115610fe357600080fd5b818701915087601f830112610ff757600080fd5b8135818111156110095761100961138d565b604051601f8201601f19908116603f011681019083821181831017156110315761103161138d565b816040528281528a602084870101111561104a57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561108157600080fd5b61108a83610eec565b91506020830135801515811461109f57600080fd5b809150509250929050565b600080604083850312156110bd57600080fd5b6110c683610eec565b946020939093013593505050565b6000602082840312156110e657600080fd5b8135610713816113a3565b60006020828403121561110357600080fd5b8151610713816113a3565b60006020828403121561112057600080fd5b5035919050565b6000815180845261113f8160208601602086016112b5565b601f01601f19169290920160200192915050565b600083516111658184602088016112b5565b8351908301906111798183602088016112b5565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906111b590830184611127565b9695505050505050565b6020815260006107136020830184611127565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b600082198211156112855761128561134b565b500190565b60008261129957611299611361565b500490565b6000828210156112b0576112b061134b565b500390565b60005b838110156112d05781810151838201526020016112b8565b838111156106a05750506000910152565b600181811c908216806112f557607f821691505b6020821081141561131657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156113305761133061134b565b5060010190565b60008261134657611346611361565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461056b57600080fdfea264697066735822122009ec0be20bb17f8e9b57fc7dd6c9862c50e6fc5c774d5853cdf1fe4f2d3e830c64736f6c63430008060033",
385
- "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806342966c6811610097578063a22cb46511610066578063a22cb465146101ff578063b88d4fde14610212578063c87b56dd14610225578063e985e9c51461023857600080fd5b806342966c68146101b05780636352211e146101c357806370a08231146101d657806395d89b41146101f757600080fd5b8063095ea7b3116100d3578063095ea7b31461016257806323b872dd1461017757806340c10f191461018a57806342842e0e1461019d57600080fd5b806301ffc9a7146100fa57806306fdde0314610122578063081812fc14610137575b600080fd5b61010d6101083660046110d4565b610274565b60405190151581526020015b60405180910390f35b61012a6102c6565b60405161011991906111bf565b61014a61014536600461110e565b610358565b6040516001600160a01b039091168152602001610119565b6101756101703660046110aa565b61037f565b005b610175610185366004610f56565b61049a565b6101756101983660046110aa565b6104cb565b6101756101ab366004610f56565b6104d9565b6101756101be36600461110e565b6104f4565b61014a6101d136600461110e565b61056e565b6101e96101e4366004610f08565b6105ce565b604051908152602001610119565b61012a610654565b61017561020d36600461106e565b610663565b610175610220366004610f92565b61066e565b61012a61023336600461110e565b6106a6565b61010d610246366004610f23565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b14806102a557506001600160e01b03198216635b5e139f60e01b145b806102c057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102d5906112e1565b80601f0160208091040260200160405190810160405280929190818152602001828054610301906112e1565b801561034e5780601f106103235761010080835404028352916020019161034e565b820191906000526020600020905b81548152906001019060200180831161033157829003601f168201915b5050505050905090565b60006103638261071a565b506000908152600460205260409020546001600160a01b031690565b600061038a8261056e565b9050806001600160a01b0316836001600160a01b031614156103fd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061041957506104198133610246565b61048b5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016103f4565b6104958383610779565b505050565b6104a433826107e7565b6104c05760405162461bcd60e51b81526004016103f490611224565b610495838383610866565b6104d58282610a02565b5050565b6104958383836040518060200160405280600081525061066e565b336104fe8261056e565b6001600160a01b0316146105625760405162461bcd60e51b815260206004820152602560248201527f4552433732313a206275726e206f6620746f6b656e2074686174206973206e6f6044820152643a1037bbb760d91b60648201526084016103f4565b61056b81610b44565b50565b6000818152600260205260408120546001600160a01b0316806102c05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103f4565b60006001600160a01b0382166106385760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103f4565b506001600160a01b031660009081526003602052604090205490565b6060600180546102d5906112e1565b6104d5338383610bdf565b61067833836107e7565b6106945760405162461bcd60e51b81526004016103f490611224565b6106a084848484610cae565b50505050565b60606106b18261071a565b60006106c860408051602081019091526000815290565b905060008151116106e85760405180602001604052806000815250610713565b806106f284610ce1565b604051602001610703929190611153565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b031661056b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103f4565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906107ae8261056e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806107f38361056e565b9050806001600160a01b0316846001600160a01b0316148061083a57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b8061085e5750836001600160a01b031661085384610358565b6001600160a01b0316145b949350505050565b826001600160a01b03166108798261056e565b6001600160a01b0316146108dd5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016103f4565b6001600160a01b03821661093f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103f4565b61094a600082610779565b6001600160a01b038316600090815260036020526040812080546001929061097390849061129e565b90915550506001600160a01b03821660009081526003602052604081208054600192906109a1908490611272565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038216610a585760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103f4565b6000818152600260205260409020546001600160a01b031615610abd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103f4565b6001600160a01b0382166000908152600360205260408120805460019290610ae6908490611272565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610b4f8261056e565b9050610b5c600083610779565b6001600160a01b0381166000908152600360205260408120805460019290610b8590849061129e565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b816001600160a01b0316836001600160a01b03161415610c415760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103f4565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610cb9848484610866565b610cc584848484610ddf565b6106a05760405162461bcd60e51b81526004016103f4906111d2565b606081610d055750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610d2f5780610d198161131c565b9150610d289050600a8361128a565b9150610d09565b60008167ffffffffffffffff811115610d4a57610d4a61138d565b6040519080825280601f01601f191660200182016040528015610d74576020820181803683370190505b5090505b841561085e57610d8960018361129e565b9150610d96600a86611337565b610da1906030611272565b60f81b818381518110610db657610db6611377565b60200101906001600160f81b031916908160001a905350610dd8600a8661128a565b9450610d78565b60006001600160a01b0384163b15610ee157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610e23903390899088908890600401611182565b602060405180830381600087803b158015610e3d57600080fd5b505af1925050508015610e6d575060408051601f3d908101601f19168201909252610e6a918101906110f1565b60015b610ec7573d808015610e9b576040519150601f19603f3d011682016040523d82523d6000602084013e610ea0565b606091505b508051610ebf5760405162461bcd60e51b81526004016103f4906111d2565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061085e565b506001949350505050565b80356001600160a01b0381168114610f0357600080fd5b919050565b600060208284031215610f1a57600080fd5b61071382610eec565b60008060408385031215610f3657600080fd5b610f3f83610eec565b9150610f4d60208401610eec565b90509250929050565b600080600060608486031215610f6b57600080fd5b610f7484610eec565b9250610f8260208501610eec565b9150604084013590509250925092565b60008060008060808587031215610fa857600080fd5b610fb185610eec565b9350610fbf60208601610eec565b925060408501359150606085013567ffffffffffffffff80821115610fe357600080fd5b818701915087601f830112610ff757600080fd5b8135818111156110095761100961138d565b604051601f8201601f19908116603f011681019083821181831017156110315761103161138d565b816040528281528a602084870101111561104a57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561108157600080fd5b61108a83610eec565b91506020830135801515811461109f57600080fd5b809150509250929050565b600080604083850312156110bd57600080fd5b6110c683610eec565b946020939093013593505050565b6000602082840312156110e657600080fd5b8135610713816113a3565b60006020828403121561110357600080fd5b8151610713816113a3565b60006020828403121561112057600080fd5b5035919050565b6000815180845261113f8160208601602086016112b5565b601f01601f19169290920160200192915050565b600083516111658184602088016112b5565b8351908301906111798183602088016112b5565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906111b590830184611127565b9695505050505050565b6020815260006107136020830184611127565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b600082198211156112855761128561134b565b500190565b60008261129957611299611361565b500490565b6000828210156112b0576112b061134b565b500390565b60005b838110156112d05781810151838201526020016112b8565b838111156106a05750506000910152565b600181811c908216806112f557607f821691505b6020821081141561131657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156113305761133061134b565b5060010190565b60008261134657611346611361565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461056b57600080fdfea264697066735822122009ec0be20bb17f8e9b57fc7dd6c9862c50e6fc5c774d5853cdf1fe4f2d3e830c64736f6c63430008060033",
384
+ "bytecode": "0x60806040523480156200001157600080fd5b50604051620016c0380380620016c0833981016040819052620000349162000136565b818160006200004483826200022f565b5060016200005382826200022f565b5050600680546001600160a01b0319163317905550620002fb915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200009957600080fd5b81516001600160401b0380821115620000b657620000b662000071565b604051601f8301601f19908116603f01168101908282118183101715620000e157620000e162000071565b81604052838152602092508683858801011115620000fe57600080fd5b600091505b8382101562000122578582018301518183018401529082019062000103565b600093810190920192909252949350505050565b600080604083850312156200014a57600080fd5b82516001600160401b03808211156200016257600080fd5b620001708683870162000087565b935060208501519150808211156200018757600080fd5b50620001968582860162000087565b9150509250929050565b600181811c90821680620001b557607f821691505b602082108103620001d657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200022a57600081815260208120601f850160051c81016020861015620002055750805b601f850160051c820191505b81811015620002265782815560010162000211565b5050505b505050565b81516001600160401b038111156200024b576200024b62000071565b62000263816200025c8454620001a0565b84620001dc565b602080601f8311600181146200029b5760008415620002825750858301515b600019600386901b1c1916600185901b17855562000226565b600085815260208120601f198616915b82811015620002cc57888601518255948401946001909101908401620002ab565b5085821015620002eb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6113b5806200030b6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806342966c6811610097578063a22cb46511610066578063a22cb465146101ff578063b88d4fde14610212578063c87b56dd14610225578063e985e9c51461023857600080fd5b806342966c68146101b05780636352211e146101c357806370a08231146101d657806395d89b41146101f757600080fd5b8063095ea7b3116100d3578063095ea7b31461016257806323b872dd1461017757806340c10f191461018a57806342842e0e1461019d57600080fd5b806301ffc9a7146100fa57806306fdde0314610122578063081812fc14610137575b600080fd5b61010d610108366004610edc565b61024b565b60405190151581526020015b60405180910390f35b61012a61029d565b6040516101199190610f49565b61014a610145366004610f5c565b61032f565b6040516001600160a01b039091168152602001610119565b610175610170366004610f91565b610356565b005b610175610185366004610fbb565b610470565b610175610198366004610f91565b6104a1565b6101756101ab366004610fbb565b6104af565b6101756101be366004610f5c565b6104ca565b61014a6101d1366004610f5c565b610544565b6101e96101e4366004610ff7565b6105a4565b604051908152602001610119565b61012a61062a565b61017561020d366004611012565b610639565b610175610220366004611064565b610644565b61012a610233366004610f5c565b61067c565b61010d610246366004611140565b6106f0565b60006001600160e01b031982166380ac58cd60e01b148061027c57506001600160e01b03198216635b5e139f60e01b145b8061029757506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102ac90611173565b80601f01602080910402602001604051908101604052809291908181526020018280546102d890611173565b80156103255780601f106102fa57610100808354040283529160200191610325565b820191906000526020600020905b81548152906001019060200180831161030857829003601f168201915b5050505050905090565b600061033a8261071e565b506000908152600460205260409020546001600160a01b031690565b600061036182610544565b9050806001600160a01b0316836001600160a01b0316036103d35760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103ef57506103ef81336106f0565b6104615760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016103ca565b61046b838361077d565b505050565b61047a33826107eb565b6104965760405162461bcd60e51b81526004016103ca906111ad565b61046b83838361084a565b6104ab82826109e6565b5050565b61046b83838360405180602001604052806000815250610644565b336104d482610544565b6001600160a01b0316146105385760405162461bcd60e51b815260206004820152602560248201527f4552433732313a206275726e206f6620746f6b656e2074686174206973206e6f6044820152643a1037bbb760d91b60648201526084016103ca565b61054181610b28565b50565b6000818152600260205260408120546001600160a01b0316806102975760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103ca565b60006001600160a01b03821661060e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103ca565b506001600160a01b031660009081526003602052604090205490565b6060600180546102ac90611173565b6104ab338383610bc3565b61064e33836107eb565b61066a5760405162461bcd60e51b81526004016103ca906111ad565b61067684848484610c91565b50505050565b60606106878261071e565b600061069e60408051602081019091526000815290565b905060008151116106be57604051806020016040528060008152506106e9565b806106c884610cc4565b6040516020016106d99291906111fb565b6040516020818303038152906040525b9392505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000818152600260205260409020546001600160a01b03166105415760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103ca565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906107b282610544565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806107f783610544565b9050806001600160a01b0316846001600160a01b0316148061081e575061081e81856106f0565b806108425750836001600160a01b03166108378461032f565b6001600160a01b0316145b949350505050565b826001600160a01b031661085d82610544565b6001600160a01b0316146108c15760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016103ca565b6001600160a01b0382166109235760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103ca565b61092e60008261077d565b6001600160a01b0383166000908152600360205260408120805460019290610957908490611240565b90915550506001600160a01b0382166000908152600360205260408120805460019290610985908490611253565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038216610a3c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103ca565b6000818152600260205260409020546001600160a01b031615610aa15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103ca565b6001600160a01b0382166000908152600360205260408120805460019290610aca908490611253565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610b3382610544565b9050610b4060008361077d565b6001600160a01b0381166000908152600360205260408120805460019290610b69908490611240565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b816001600160a01b0316836001600160a01b031603610c245760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103ca565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610c9c84848461084a565b610ca884848484610dc5565b6106765760405162461bcd60e51b81526004016103ca90611266565b606081600003610ceb5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610d155780610cff816112b8565b9150610d0e9050600a836112e7565b9150610cef565b60008167ffffffffffffffff811115610d3057610d3061104e565b6040519080825280601f01601f191660200182016040528015610d5a576020820181803683370190505b5090505b841561084257610d6f600183611240565b9150610d7c600a866112fb565b610d87906030611253565b60f81b818381518110610d9c57610d9c61130f565b60200101906001600160f81b031916908160001a905350610dbe600a866112e7565b9450610d5e565b60006001600160a01b0384163b15610ebb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610e09903390899088908890600401611325565b6020604051808303816000875af1925050508015610e44575060408051601f3d908101601f19168201909252610e4191810190611362565b60015b610ea1573d808015610e72576040519150601f19603f3d011682016040523d82523d6000602084013e610e77565b606091505b508051600003610e995760405162461bcd60e51b81526004016103ca90611266565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610842565b506001949350505050565b6001600160e01b03198116811461054157600080fd5b600060208284031215610eee57600080fd5b81356106e981610ec6565b60005b83811015610f14578181015183820152602001610efc565b50506000910152565b60008151808452610f35816020860160208601610ef9565b601f01601f19169290920160200192915050565b6020815260006106e96020830184610f1d565b600060208284031215610f6e57600080fd5b5035919050565b80356001600160a01b0381168114610f8c57600080fd5b919050565b60008060408385031215610fa457600080fd5b610fad83610f75565b946020939093013593505050565b600080600060608486031215610fd057600080fd5b610fd984610f75565b9250610fe760208501610f75565b9150604084013590509250925092565b60006020828403121561100957600080fd5b6106e982610f75565b6000806040838503121561102557600080fd5b61102e83610f75565b91506020830135801515811461104357600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561107a57600080fd5b61108385610f75565b935061109160208601610f75565b925060408501359150606085013567ffffffffffffffff808211156110b557600080fd5b818701915087601f8301126110c957600080fd5b8135818111156110db576110db61104e565b604051601f8201601f19908116603f011681019083821181831017156111035761110361104e565b816040528281528a602084870101111561111c57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561115357600080fd5b61115c83610f75565b915061116a60208401610f75565b90509250929050565b600181811c9082168061118757607f821691505b6020821081036111a757634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6000835161120d818460208801610ef9565b835190830190611221818360208801610ef9565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156102975761029761122a565b808201808211156102975761029761122a565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000600182016112ca576112ca61122a565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826112f6576112f66112d1565b500490565b60008261130a5761130a6112d1565b500690565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061135890830184610f1d565b9695505050505050565b60006020828403121561137457600080fd5b81516106e981610ec656fea2646970667358221220b202a5d558cf5ad17e44ab52fbcaed2cc66ba0a84dc0aa75e1a6c6ab22be0a1b64736f6c63430008100033",
385
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806342966c6811610097578063a22cb46511610066578063a22cb465146101ff578063b88d4fde14610212578063c87b56dd14610225578063e985e9c51461023857600080fd5b806342966c68146101b05780636352211e146101c357806370a08231146101d657806395d89b41146101f757600080fd5b8063095ea7b3116100d3578063095ea7b31461016257806323b872dd1461017757806340c10f191461018a57806342842e0e1461019d57600080fd5b806301ffc9a7146100fa57806306fdde0314610122578063081812fc14610137575b600080fd5b61010d610108366004610edc565b61024b565b60405190151581526020015b60405180910390f35b61012a61029d565b6040516101199190610f49565b61014a610145366004610f5c565b61032f565b6040516001600160a01b039091168152602001610119565b610175610170366004610f91565b610356565b005b610175610185366004610fbb565b610470565b610175610198366004610f91565b6104a1565b6101756101ab366004610fbb565b6104af565b6101756101be366004610f5c565b6104ca565b61014a6101d1366004610f5c565b610544565b6101e96101e4366004610ff7565b6105a4565b604051908152602001610119565b61012a61062a565b61017561020d366004611012565b610639565b610175610220366004611064565b610644565b61012a610233366004610f5c565b61067c565b61010d610246366004611140565b6106f0565b60006001600160e01b031982166380ac58cd60e01b148061027c57506001600160e01b03198216635b5e139f60e01b145b8061029757506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102ac90611173565b80601f01602080910402602001604051908101604052809291908181526020018280546102d890611173565b80156103255780601f106102fa57610100808354040283529160200191610325565b820191906000526020600020905b81548152906001019060200180831161030857829003601f168201915b5050505050905090565b600061033a8261071e565b506000908152600460205260409020546001600160a01b031690565b600061036182610544565b9050806001600160a01b0316836001600160a01b0316036103d35760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103ef57506103ef81336106f0565b6104615760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016103ca565b61046b838361077d565b505050565b61047a33826107eb565b6104965760405162461bcd60e51b81526004016103ca906111ad565b61046b83838361084a565b6104ab82826109e6565b5050565b61046b83838360405180602001604052806000815250610644565b336104d482610544565b6001600160a01b0316146105385760405162461bcd60e51b815260206004820152602560248201527f4552433732313a206275726e206f6620746f6b656e2074686174206973206e6f6044820152643a1037bbb760d91b60648201526084016103ca565b61054181610b28565b50565b6000818152600260205260408120546001600160a01b0316806102975760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103ca565b60006001600160a01b03821661060e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103ca565b506001600160a01b031660009081526003602052604090205490565b6060600180546102ac90611173565b6104ab338383610bc3565b61064e33836107eb565b61066a5760405162461bcd60e51b81526004016103ca906111ad565b61067684848484610c91565b50505050565b60606106878261071e565b600061069e60408051602081019091526000815290565b905060008151116106be57604051806020016040528060008152506106e9565b806106c884610cc4565b6040516020016106d99291906111fb565b6040516020818303038152906040525b9392505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000818152600260205260409020546001600160a01b03166105415760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103ca565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906107b282610544565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806107f783610544565b9050806001600160a01b0316846001600160a01b0316148061081e575061081e81856106f0565b806108425750836001600160a01b03166108378461032f565b6001600160a01b0316145b949350505050565b826001600160a01b031661085d82610544565b6001600160a01b0316146108c15760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016103ca565b6001600160a01b0382166109235760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103ca565b61092e60008261077d565b6001600160a01b0383166000908152600360205260408120805460019290610957908490611240565b90915550506001600160a01b0382166000908152600360205260408120805460019290610985908490611253565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038216610a3c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103ca565b6000818152600260205260409020546001600160a01b031615610aa15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103ca565b6001600160a01b0382166000908152600360205260408120805460019290610aca908490611253565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610b3382610544565b9050610b4060008361077d565b6001600160a01b0381166000908152600360205260408120805460019290610b69908490611240565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b816001600160a01b0316836001600160a01b031603610c245760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103ca565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610c9c84848461084a565b610ca884848484610dc5565b6106765760405162461bcd60e51b81526004016103ca90611266565b606081600003610ceb5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610d155780610cff816112b8565b9150610d0e9050600a836112e7565b9150610cef565b60008167ffffffffffffffff811115610d3057610d3061104e565b6040519080825280601f01601f191660200182016040528015610d5a576020820181803683370190505b5090505b841561084257610d6f600183611240565b9150610d7c600a866112fb565b610d87906030611253565b60f81b818381518110610d9c57610d9c61130f565b60200101906001600160f81b031916908160001a905350610dbe600a866112e7565b9450610d5e565b60006001600160a01b0384163b15610ebb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610e09903390899088908890600401611325565b6020604051808303816000875af1925050508015610e44575060408051601f3d908101601f19168201909252610e4191810190611362565b60015b610ea1573d808015610e72576040519150601f19603f3d011682016040523d82523d6000602084013e610e77565b606091505b508051600003610e995760405162461bcd60e51b81526004016103ca90611266565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610842565b506001949350505050565b6001600160e01b03198116811461054157600080fd5b600060208284031215610eee57600080fd5b81356106e981610ec6565b60005b83811015610f14578181015183820152602001610efc565b50506000910152565b60008151808452610f35816020860160208601610ef9565b601f01601f19169290920160200192915050565b6020815260006106e96020830184610f1d565b600060208284031215610f6e57600080fd5b5035919050565b80356001600160a01b0381168114610f8c57600080fd5b919050565b60008060408385031215610fa457600080fd5b610fad83610f75565b946020939093013593505050565b600080600060608486031215610fd057600080fd5b610fd984610f75565b9250610fe760208501610f75565b9150604084013590509250925092565b60006020828403121561100957600080fd5b6106e982610f75565b6000806040838503121561102557600080fd5b61102e83610f75565b91506020830135801515811461104357600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561107a57600080fd5b61108385610f75565b935061109160208601610f75565b925060408501359150606085013567ffffffffffffffff808211156110b557600080fd5b818701915087601f8301126110c957600080fd5b8135818111156110db576110db61104e565b604051601f8201601f19908116603f011681019083821181831017156111035761110361104e565b816040528281528a602084870101111561111c57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561115357600080fd5b61115c83610f75565b915061116a60208401610f75565b90509250929050565b600181811c9082168061118757607f821691505b6020821081036111a757634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6000835161120d818460208801610ef9565b835190830190611221818360208801610ef9565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156102975761029761122a565b808201808211156102975761029761122a565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000600182016112ca576112ca61122a565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826112f6576112f66112d1565b500490565b60008261130a5761130a6112d1565b500690565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061135890830184610f1d565b9695505050505050565b60006020828403121561137457600080fd5b81516106e981610ec656fea2646970667358221220b202a5d558cf5ad17e44ab52fbcaed2cc66ba0a84dc0aa75e1a6c6ab22be0a1b64736f6c63430008100033",
386
386
  "linkReferences": {},
387
387
  "deployedLinkReferences": {}
388
388
  }
@@ -9,6 +9,16 @@ import {IAccessManager} from "./interfaces/IAccessManager.sol";
9
9
  /**
10
10
  * @title AccessManager - Protocol access roles
11
11
  * @dev Contract that holds the access roles for PolicyPool and other components of the protocol.
12
+ *
13
+ * [CAUTION]
14
+ * ====
15
+ * Avoid leaving a this contract without DEFAULT_ADMIN_ROLE.
16
+ *
17
+ * This contract includes the methods `revokeRole()` and `renounceRole()` that allow to revoke or renounce to
18
+ * specific roles. Even when there are valid reasons to leave these methods (for example revoking the initial
19
+ * DEFAULT_ADMIN_ROLE of the deployer account to leave just the governance account), it's good to mention these
20
+ * methods have to be used with care, avoiding leaving the contract without any default admin.
21
+ *
12
22
  * @custom:security-contact security@ensuro.co
13
23
  * @author Ensuro
14
24
  */
@@ -24,6 +34,11 @@ contract AccessManager is Initializable, AccessControlUpgradeable, UUPSUpgradeab
24
34
  _;
25
35
  }
26
36
 
37
+ /// @custom:oz-upgrades-unsafe-allow constructor
38
+ constructor() {
39
+ _disableInitializers();
40
+ }
41
+
27
42
  function initialize() public initializer {
28
43
  __AccessControl_init();
29
44
  __UUPSUpgradeable_init();
@@ -31,13 +46,20 @@ contract AccessManager is Initializable, AccessControlUpgradeable, UUPSUpgradeab
31
46
  }
32
47
 
33
48
  // solhint-disable-next-line func-name-mixedcase
34
- function __AccessManager_init_unchained() internal initializer {
35
- _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
49
+ function __AccessManager_init_unchained() internal onlyInitializing {
50
+ _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
36
51
  }
37
52
 
38
53
  // solhint-disable-next-line no-empty-blocks
39
54
  function _authorizeUpgrade(address) internal override onlyRole2(GUARDIAN_ROLE, LEVEL1_ROLE) {}
40
55
 
56
+ /**
57
+ * @dev See {IERC165-supportsInterface}.
58
+ */
59
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
60
+ return super.supportsInterface(interfaceId) || interfaceId == type(IAccessManager).interfaceId;
61
+ }
62
+
41
63
  function getComponentRole(address component, bytes32 role)
42
64
  public
43
65
  pure
@@ -100,4 +122,11 @@ contract AccessManager is Initializable, AccessControlUpgradeable, UUPSUpgradeab
100
122
  ) external onlyRole(getRoleAdmin(getComponentRole(component, role))) {
101
123
  _grantRole(getComponentRole(component, role), account);
102
124
  }
125
+
126
+ /**
127
+ * @dev This empty reserved space is put in place to allow future versions to add new
128
+ * variables without shifting down storage in the inheritance chain.
129
+ * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
130
+ */
131
+ uint256[50] private __gap;
103
132
  }
@@ -1,20 +1,26 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.0;
3
3
 
4
- import {LiquidityThresholdAssetManager} from "./LiquidityThresholdAssetManager.sol";
4
+ import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
5
5
  import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
6
6
  import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol";
7
+ import {LiquidityThresholdAssetManager} from "./LiquidityThresholdAssetManager.sol";
7
8
 
8
9
  /**
9
10
  * @title Asset Manager that deploys the funds into an ERC4626 vault
10
11
  * @dev Using liquidity thresholds defined in {LiquidityThresholdAssetManager}, deploys the funds into an ERC4626 vault.
11
12
  * @custom:security-contact security@ensuro.co
12
13
  * @author Ensuro
14
+ *
15
+ * @notice This contracts uses Diamond Storage and should not define state variables outside of that. See the diamondStorage method for more details.
13
16
  */
14
17
  contract ERC4626AssetManager is LiquidityThresholdAssetManager {
18
+ using SafeCast for uint256;
19
+
15
20
  IERC4626 internal immutable _vault;
16
21
 
17
22
  constructor(IERC20Metadata asset_, IERC4626 vault_) LiquidityThresholdAssetManager(asset_) {
23
+ require(address(vault_) != address(0), "ERC4626AssetManager: vault cannot be zero address");
18
24
  _vault = vault_;
19
25
  }
20
26
 
@@ -37,7 +43,7 @@ contract ERC4626AssetManager is LiquidityThresholdAssetManager {
37
43
  DiamondStorage storage ds = diamondStorage();
38
44
  uint256 assets = _vault.redeem(_vault.balanceOf(address(this)), address(this), address(this));
39
45
  earnings = int256(assets) - int256(uint256(ds.lastInvestmentValue));
40
- ds.lastInvestmentValue = uint128(assets);
46
+ ds.lastInvestmentValue = assets.toUint128();
41
47
  emit MoneyDeinvested(assets);
42
48
  emit EarningsRecorded(earnings);
43
49
  return earnings;
@@ -1,8 +1,11 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.0;
3
3
 
4
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
4
5
  import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
5
6
  import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
7
+ import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
8
+ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
6
9
  import {IPolicyPool} from "./interfaces/IPolicyPool.sol";
7
10
  import {Reserve} from "./Reserve.sol";
8
11
  import {IEToken} from "./interfaces/IEToken.sol";
@@ -10,7 +13,7 @@ import {IAccessManager} from "./interfaces/IAccessManager.sol";
10
13
  import {IPolicyPoolComponent} from "./interfaces/IPolicyPoolComponent.sol";
11
14
  import {ILPWhitelist} from "./interfaces/ILPWhitelist.sol";
12
15
  import {IAssetManager} from "./interfaces/IAssetManager.sol";
13
- import {WadRayMath} from "./WadRayMath.sol";
16
+ import {WadRayMath} from "./dependencies/WadRayMath.sol";
14
17
  import {TimeScaled} from "./TimeScaled.sol";
15
18
 
16
19
  /**
@@ -27,8 +30,14 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
27
30
  using WadRayMath for uint256;
28
31
  using TimeScaled for TimeScaled.ScaledAmount;
29
32
  using SafeERC20 for IERC20Metadata;
33
+ using SafeCast for uint256;
30
34
 
31
- uint256 internal constant SECONDS_PER_YEAR = 365 days;
35
+ uint256 internal constant FOUR_DECIMAL_TO_WAD = 1e14;
36
+ uint16 internal constant HUNDRED_PERCENT = 1e4;
37
+ uint16 internal constant MAX_UR_MIN = 5e3; // 50% - Minimum value for Max Utilization Rate
38
+ uint16 internal constant LIQ_REQ_MIN = 8e3; // 80%
39
+ uint16 internal constant LIQ_REQ_MAX = 13e3; // 130%
40
+ uint16 internal constant INT_LOAN_IR_MAX = 5e3; // 50% - Maximum value for InternalLoan interest rate
32
41
 
33
42
  // Attributes taken from ERC20
34
43
  mapping(address => uint256) private _balances;
@@ -89,7 +98,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
89
98
  uint256 maxUtilizationRate_,
90
99
  uint256 internalLoanInterestRate_
91
100
  ) public initializer {
92
- __PolicyPoolComponent_init();
101
+ __Reserve_init();
93
102
  __EToken_init_unchained(name_, symbol_, maxUtilizationRate_, internalLoanInterestRate_);
94
103
  }
95
104
 
@@ -99,7 +108,9 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
99
108
  string memory symbol_,
100
109
  uint256 maxUtilizationRate_,
101
110
  uint256 internalLoanInterestRate_
102
- ) internal initializer {
111
+ ) internal onlyInitializing {
112
+ require(bytes(name_).length > 0, "EToken: name cannot be empty");
113
+ require(bytes(symbol_).length > 0, "EToken: symbol cannot be empty");
103
114
  _name = name_;
104
115
  _symbol = symbol_;
105
116
  _tsScaled.init();
@@ -109,29 +120,52 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
109
120
  tokenInterestRate: 0
110
121
  }); */
111
122
  _params = PackedParams({
112
- maxUtilizationRate: uint16(maxUtilizationRate_ / 1e14),
113
- liquidityRequirement: 1e4,
123
+ maxUtilizationRate: _wadTo4(maxUtilizationRate_),
124
+ liquidityRequirement: HUNDRED_PERCENT,
114
125
  minUtilizationRate: 0,
115
- internalLoanInterestRate: uint16(internalLoanInterestRate_ / 1e14),
126
+ internalLoanInterestRate: _wadTo4(internalLoanInterestRate_),
116
127
  whitelist: ILPWhitelist(address(0))
117
128
  });
118
129
 
119
130
  _validateParameters();
120
131
  }
121
132
 
133
+ /**
134
+ * @dev See {IERC165-supportsInterface}.
135
+ */
136
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
137
+ return
138
+ super.supportsInterface(interfaceId) ||
139
+ interfaceId == type(IERC20).interfaceId ||
140
+ interfaceId == type(IERC20Metadata).interfaceId ||
141
+ interfaceId == type(IEToken).interfaceId;
142
+ }
143
+
122
144
  // runs validation on EToken parameters
123
145
  function _validateParameters() internal view override {
124
146
  require(
125
- _params.liquidityRequirement >= 8e3 && _params.liquidityRequirement <= 13e3,
147
+ _params.liquidityRequirement >= LIQ_REQ_MIN && _params.liquidityRequirement <= LIQ_REQ_MAX,
126
148
  "Validation: liquidityRequirement must be [0.8, 1.3]"
127
149
  );
128
150
  require(
129
- _params.maxUtilizationRate >= 5e3 && _params.maxUtilizationRate <= 1e4,
151
+ _params.maxUtilizationRate >= MAX_UR_MIN && _params.maxUtilizationRate <= HUNDRED_PERCENT,
130
152
  "Validation: maxUtilizationRate must be [0.5, 1]"
131
153
  );
132
- require(_params.minUtilizationRate <= 1e4, "Validation: minUtilizationRate must be [0, 1]");
133
154
  require(
134
- _params.internalLoanInterestRate <= 5e3,
155
+ _params.minUtilizationRate <= HUNDRED_PERCENT,
156
+ "Validation: minUtilizationRate must be [0, 1]"
157
+ );
158
+ /*
159
+ * We don't validate minUtilizationRate < maxUtilizationRate because the opposite is valid too.
160
+ * These limits aren't strong limits on the values the utilization rate can take, but instead they are
161
+ * limits on specific operations.
162
+ * `minUtilizationRate` is used to avoid new deposits to dilute the yields of existing LPs, but it doesn't
163
+ * prevent the UR from going down in other operations (`unlockScr` for example).
164
+ * `maxUtilizationRate` is used to prevent selling more coverage when UR is too high, only checked on `lockScr`
165
+ * operations, but not in withdrawals or other operations.
166
+ */
167
+ require(
168
+ _params.internalLoanInterestRate <= INT_LOAN_IR_MAX,
135
169
  "Validation: internalLoanInterestRate must be <= 50%"
136
170
  );
137
171
  }
@@ -242,15 +276,34 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
242
276
  address recipient,
243
277
  uint256 amount
244
278
  ) public virtual override returns (bool) {
279
+ address spender = _msgSender();
280
+ _spendAllowance(sender, spender, amount);
245
281
  _transfer(sender, recipient, amount);
246
-
247
- uint256 currentAllowance = _allowances[sender][_msgSender()];
248
- require(currentAllowance >= amount, "EToken: transfer amount exceeds allowance");
249
- _approve(sender, _msgSender(), currentAllowance - amount);
250
-
251
282
  return true;
252
283
  }
253
284
 
285
+ /**
286
+ * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
287
+ *
288
+ * Does not update the allowance amount in case of infinite allowance.
289
+ * Revert if not enough allowance is available.
290
+ *
291
+ * Might emit an {Approval} event.
292
+ */
293
+ function _spendAllowance(
294
+ address owner,
295
+ address spender,
296
+ uint256 amount
297
+ ) internal virtual {
298
+ uint256 currentAllowance = allowance(owner, spender);
299
+ if (currentAllowance != type(uint256).max) {
300
+ require(currentAllowance >= amount, "EToken: insufficient allowance");
301
+ unchecked {
302
+ _approve(owner, spender, currentAllowance - amount);
303
+ }
304
+ }
305
+ }
306
+
254
307
  /**
255
308
  * @dev Atomically increases the allowance granted to `spender` by the caller.
256
309
  *
@@ -264,7 +317,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
264
317
  * - `spender` cannot be the zero address.
265
318
  */
266
319
  function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
267
- _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
320
+ _approve(_msgSender(), spender, allowance(_msgSender(), spender) + addedValue);
268
321
  return true;
269
322
  }
270
323
 
@@ -338,6 +391,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
338
391
  */
339
392
  function _mint(address account, uint256 amount) internal virtual {
340
393
  require(account != address(0), "EToken: mint to the zero address");
394
+ require(amount > 0, "EToken: amount to mint should be greater than zero");
341
395
 
342
396
  _beforeTokenTransfer(address(0), account, amount);
343
397
  uint256 scaledAmount = _tsScaled.add(amount, tokenInterestRate());
@@ -427,9 +481,10 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
427
481
  uint256 totalSupply_ = this.totalSupply();
428
482
  if (totalSupply_ == 0) _scr.tokenInterestRate = 0;
429
483
  else {
430
- _scr.tokenInterestRate = uint64(
431
- uint256(_scr.interestRate).wadMul(uint256(_scr.scr)).wadDiv(totalSupply_)
432
- );
484
+ _scr.tokenInterestRate = uint256(_scr.interestRate)
485
+ .wadMul(uint256(_scr.scr))
486
+ .wadDiv(totalSupply_)
487
+ .toUint64();
433
488
  }
434
489
  }
435
490
 
@@ -459,6 +514,17 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
459
514
  _assetManager = newAM;
460
515
  }
461
516
 
517
+ // solhint-disable-next-line func-name-mixedcase
518
+ function _4toWad(uint16 value) internal pure returns (uint256) {
519
+ // 4 decimals to Wad (18 decimals)
520
+ return uint256(value) * FOUR_DECIMAL_TO_WAD;
521
+ }
522
+
523
+ function _wadTo4(uint256 value) internal pure returns (uint16) {
524
+ // Wad to 4 decimals
525
+ return (value / FOUR_DECIMAL_TO_WAD).toUint16();
526
+ }
527
+
462
528
  function scr() public view virtual override returns (uint256) {
463
529
  return uint256(_scr.scr);
464
530
  }
@@ -472,15 +538,15 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
472
538
  }
473
539
 
474
540
  function liquidityRequirement() public view returns (uint256) {
475
- return uint256(_params.liquidityRequirement) * 1e14; // 4 -> 18 decimals
541
+ return _4toWad(_params.liquidityRequirement);
476
542
  }
477
543
 
478
544
  function maxUtilizationRate() public view returns (uint256) {
479
- return uint256(_params.maxUtilizationRate) * 1e14; // 4 -> 18 decimals
545
+ return _4toWad(_params.maxUtilizationRate);
480
546
  }
481
547
 
482
548
  function minUtilizationRate() public view returns (uint256) {
483
- return uint256(_params.minUtilizationRate) * 1e14; // 4 -> 18 decimals
549
+ return _4toWad(_params.minUtilizationRate);
484
550
  }
485
551
 
486
552
  function utilizationRate() public view returns (uint256) {
@@ -495,21 +561,18 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
495
561
  {
496
562
  require(
497
563
  scrAmount <= this.fundsAvailableToLock(),
498
- "Not enought funds available to cover the SCR"
564
+ "Not enough funds available to cover the SCR"
499
565
  );
500
566
  _tsScaled.updateScale(tokenInterestRate());
501
567
  if (_scr.scr == 0) {
502
- _scr.scr = uint128(scrAmount);
503
- _scr.interestRate = uint64(policyInterestRate);
568
+ _scr.scr = scrAmount.toUint128();
569
+ _scr.interestRate = policyInterestRate.toUint64();
504
570
  } else {
505
571
  uint256 origScr = uint256(_scr.scr);
506
572
  uint256 newScr = origScr + scrAmount;
507
- _scr.interestRate = uint64(
508
- (uint256(_scr.interestRate).wadMul(origScr) + policyInterestRate.wadMul(scrAmount)).wadDiv(
509
- newScr
510
- )
511
- );
512
- _scr.scr = uint128(newScr);
573
+ _scr.interestRate = (uint256(_scr.interestRate).wadMul(origScr) +
574
+ policyInterestRate.wadMul(scrAmount)).wadDiv(newScr).toUint64();
575
+ _scr.scr = newScr.toUint128();
513
576
  }
514
577
  emit SCRLocked(policyInterestRate, scrAmount);
515
578
  _updateTokenInterestRate();
@@ -519,7 +582,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
519
582
  uint256 scrAmount,
520
583
  uint256 policyInterestRate,
521
584
  int256 adjustment
522
- ) external override onlyBorrower {
585
+ ) external override onlyBorrower whenNotPaused {
523
586
  require(scrAmount <= uint256(_scr.scr), "Current SCR less than the amount you want to unlock");
524
587
  _tsScaled.updateScale(tokenInterestRate());
525
588
 
@@ -529,12 +592,9 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
529
592
  } else {
530
593
  uint256 origScr = uint256(_scr.scr);
531
594
  uint256 newScr = origScr - scrAmount;
532
- _scr.interestRate = uint64(
533
- (uint256(_scr.interestRate).wadMul(origScr) - policyInterestRate.wadMul(scrAmount)).wadDiv(
534
- newScr
535
- )
536
- );
537
- _scr.scr = uint128(newScr);
595
+ _scr.interestRate = (uint256(_scr.interestRate).wadMul(origScr) -
596
+ policyInterestRate.wadMul(scrAmount)).wadDiv(newScr).toUint64();
597
+ _scr.scr = newScr.toUint128();
538
598
  }
539
599
  emit SCRUnlocked(policyInterestRate, scrAmount);
540
600
  _discreteChange(adjustment);
@@ -579,11 +639,13 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
579
639
  onlyPolicyPool
580
640
  returns (uint256)
581
641
  {
582
- uint256 balance = balanceOf(provider);
583
- if (balance == 0) return 0;
584
- if (amount > balance) amount = balance;
585
- uint256 withdrawable = totalWithdrawable();
586
- if (amount > withdrawable) amount = withdrawable;
642
+ /**
643
+ * Here we don't check for maxUtilizationRate because that limit only affects locking more capital (`lockScr`), but
644
+ * doesn't affects the right of liquidity providers to withdraw their funds.
645
+ * The only limit for withdraws is the `totalWithdrawable()` function, that's affected by the relation between the
646
+ * scr and the totalSupply.
647
+ */
648
+ amount = Math.min(amount, Math.min(balanceOf(provider), totalWithdrawable()));
587
649
  if (amount == 0) return 0;
588
650
  _burn(provider, amount);
589
651
  _updateTokenInterestRate();
@@ -592,6 +654,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
592
654
  }
593
655
 
594
656
  function addBorrower(address borrower) external override onlyPolicyPool {
657
+ require(borrower != address(0), "EToken: Borrower cannot be the zero address");
595
658
  TimeScaled.ScaledAmount storage loan = _loans[borrower];
596
659
  if (loan.scale == 0) {
597
660
  loan.init();
@@ -600,6 +663,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
600
663
  }
601
664
 
602
665
  function removeBorrower(address borrower) external override onlyPolicyPool {
666
+ require(borrower != address(0), "EToken: Borrower cannot be the zero address");
603
667
  uint256 defaultedDebt = getLoan(borrower);
604
668
  delete _loans[borrower];
605
669
  emit InternalBorrowerRemoved(borrower, defaultedDebt);
@@ -611,12 +675,11 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
611
675
  bool fromAvailable
612
676
  ) external override onlyBorrower whenNotPaused returns (uint256) {
613
677
  uint256 amountAsked = amount;
614
- if (fromAvailable && amount > fundsAvailable()) amount = fundsAvailable();
615
- if (!fromAvailable && amount > totalSupply()) amount = totalSupply();
616
- if (amount > _tsScaled.maxNegativeAdjustment(tokenInterestRate())) {
617
- amount = _tsScaled.maxNegativeAdjustment(tokenInterestRate());
618
- if (amount == 0) return amountAsked;
619
- }
678
+ amount = Math.min(
679
+ Math.min(amount, fromAvailable ? fundsAvailable() : totalSupply()),
680
+ _tsScaled.maxNegativeAdjustment(tokenInterestRate())
681
+ );
682
+ if (amount == 0) return amountAsked;
620
683
  TimeScaled.ScaledAmount storage loan = _loans[_msgSender()];
621
684
  loan.add(amount, internalLoanInterestRate());
622
685
  _discreteChange(-int256(amount));
@@ -625,24 +688,25 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
625
688
  return amountAsked - amount;
626
689
  }
627
690
 
628
- function repayLoan(uint256 amount, address onBehalfOf) external override {
691
+ function repayLoan(uint256 amount, address onBehalfOf) external override whenNotPaused {
692
+ require(amount > 0, "EToken: amount should be greater than zero.");
629
693
  // Anyone can call this method, since it has to pay
630
- currency().safeTransferFrom(_msgSender(), address(this), amount);
631
694
  TimeScaled.ScaledAmount storage loan = _loans[onBehalfOf];
632
695
  require(loan.scale != 0, "Not a registered borrower");
633
696
  loan.sub(amount, internalLoanInterestRate());
634
697
  _discreteChange(int256(amount));
635
698
  emit InternalLoanRepaid(onBehalfOf, amount);
699
+ // Interaction at the end for security reasons
700
+ currency().safeTransferFrom(_msgSender(), address(this), amount);
636
701
  }
637
702
 
638
703
  function getLoan(address borrower) public view virtual override returns (uint256) {
639
704
  TimeScaled.ScaledAmount storage loan = _loans[borrower];
640
- if (loan.scale == 0) return 0;
641
705
  return loan.getScaledAmount(internalLoanInterestRate());
642
706
  }
643
707
 
644
708
  function internalLoanInterestRate() public view returns (uint256) {
645
- return uint256(_params.internalLoanInterestRate) * 1e14; // to wad 4 -> 18 digits
709
+ return _4toWad(_params.internalLoanInterestRate);
646
710
  }
647
711
 
648
712
  function setParam(Parameter param, uint256 newValue)
@@ -655,19 +719,19 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
655
719
  !tweak || _isTweakWad(liquidityRequirement(), newValue, 1e17),
656
720
  "Tweak exceeded: liquidityRequirement tweaks only up to 10%"
657
721
  );
658
- _params.liquidityRequirement = uint16(newValue / 1e14);
722
+ _params.liquidityRequirement = _wadTo4(newValue);
659
723
  } else if (param == Parameter.minUtilizationRate) {
660
724
  require(
661
725
  !tweak || _isTweakWad(minUtilizationRate(), newValue, 3e17),
662
726
  "Tweak exceeded: minUtilizationRate tweaks only up to 30%"
663
727
  );
664
- _params.minUtilizationRate = uint16(newValue / 1e14);
728
+ _params.minUtilizationRate = _wadTo4(newValue);
665
729
  } else if (param == Parameter.maxUtilizationRate) {
666
730
  require(
667
731
  !tweak || _isTweakWad(maxUtilizationRate(), newValue, 3e17),
668
732
  "Tweak exceeded: maxUtilizationRate tweaks only up to 30%"
669
733
  );
670
- _params.maxUtilizationRate = uint16(newValue / 1e14);
734
+ _params.maxUtilizationRate = _wadTo4(newValue);
671
735
  } else if (param == Parameter.internalLoanInterestRate) {
672
736
  require(
673
737
  !tweak || _isTweakWad(internalLoanInterestRate(), newValue, 3e17),
@@ -677,9 +741,7 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
677
741
  // So, if interest rate goes from 5% to 6%, this change will be retroactive to the lastUpdate of each
678
742
  // loan. Since it's a permissioned call, I'm ok with this. If a caller wants to reduce the impact, it can
679
743
  // issue 1 wei repayLoan to each active loan, forcing the update of the scales
680
- _params.internalLoanInterestRate = uint16(newValue / 1e14);
681
- } else {
682
- revert("Invalid param!");
744
+ _params.internalLoanInterestRate = _wadTo4(newValue);
683
745
  }
684
746
  _parameterChanged(
685
747
  IAccessManager.GovernanceActions(
@@ -706,4 +768,11 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
706
768
  function whitelist() external view returns (ILPWhitelist) {
707
769
  return _params.whitelist;
708
770
  }
771
+
772
+ /**
773
+ * @dev This empty reserved space is put in place to allow future versions to add new
774
+ * variables without shifting down storage in the inheritance chain.
775
+ * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
776
+ */
777
+ uint256[41] private __gap;
709
778
  }
@@ -34,8 +34,17 @@ contract LPManualWhitelist is ILPWhitelist, PolicyPoolComponent {
34
34
  external
35
35
  onlyComponentRole(LP_WHITELIST_ROLE)
36
36
  {
37
- _whitelisted[provider] = whitelisted;
38
- emit LPWhitelisted(provider, whitelisted);
37
+ if (_whitelisted[provider] != whitelisted) {
38
+ _whitelisted[provider] = whitelisted;
39
+ emit LPWhitelisted(provider, whitelisted);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * @dev See {IERC165-supportsInterface}.
45
+ */
46
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
47
+ return super.supportsInterface(interfaceId) || interfaceId == type(ILPWhitelist).interfaceId;
39
48
  }
40
49
 
41
50
  function acceptsDeposit(
@@ -54,4 +63,11 @@ contract LPManualWhitelist is ILPWhitelist, PolicyPoolComponent {
54
63
  ) external view override returns (bool) {
55
64
  return _whitelisted[providerTo];
56
65
  }
66
+
67
+ /**
68
+ * @dev This empty reserved space is put in place to allow future versions to add new
69
+ * variables without shifting down storage in the inheritance chain.
70
+ * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
71
+ */
72
+ uint256[49] private __gap;
57
73
  }