-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Asset Pool Underwriter Token (COV) #6
Conversation
Underwriter tokens represent an ownership share in the underlying collateral of the asset-specific pool. Underwriter tokens are minted when a user deposits ERC20 tokens into asset-specific pool and they are burned when a user exits the position. Underwriter tokens natively support meta transactions. Users can authorize a transfer of their underwriter tokens with a signature conforming EIP712 standard, rather than an on-chain transaction from their address. Anyone can submit this signature on the user's behalf by calling the permit function, as specified in EIP2612 standard, paying gas fees, and possibly performing other actions in the same transaction. The implementation mostly mirrors UniswapV2ERC20 contract adding some tweaks from OpenZeppelin ERC20 implementation such as meaningful revert messages and Approval event emitted on calls to transferFrom. This allows applications to reconstruct the allowance for all accounts just by listening to said events. Other implementations of the EIP may not emit these events, as it isn't required by the specification and UniswapV2ERC20 is one of them. Unit tests were based on OpenZeppelin ERC20 unit tests with our own tests implementation for EIP2612 and EIP712 functions. Last but not least, this token contract can be cloned using EIP1167 mechanism.
Open questions (things I do not want to address in this PR): There is a problem with ethlint and There is an open question on how Asset-specific pools and their corresponding COV tokens will be created. The implementation proposed in this PR allows for EIP1167 cloning but we may want to use CREATE2 opcode. Asset-specific pool creation may be more expensive with CREATE2 but calls to the token and to the pool may be less expensive later as they would not require a DELEGATECALL. Something to decide about later. FWIW, Uniswap uses CREATE2 to create a new pair. |
5cfc129
to
d6a0018
Compare
ethers will be imported from hardhat.config.js via require to hardhat-waffle.
It is easier to understand now, we shouldn't have it buried too deep in assertions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Big question I have here — why not make use of the OpenZeppelin ERC-20 helpers?
I should make it more clear in the PR description, sorry. I wanted to add support for EIP2612 I do not think OpenZeppelin have quite recently added I was on the fence and finally decided to copy (audited) Uniswap implementation and do two changes in other (non-permit) functionalities: add revert messages for SafeMath reverts and zero addresses just like they are done in OpenZeppelin, plus add a way to create a token with clone factory (waived in the next PR as a premature optimization). I was not happy with Uniswap tests for the token so decided to port OpenZeppelin tests to satisfy my internal need for paranoid test coverage and implemented more test cases for EIP2612 permit as Uniswap has only one test for this functionality. For what is worth, I was also trying to extend v3 OpenZeppelin ERC20 and add permit functionality copy-pasting it from Uniswap implementation but it does not feel right given that I had to overwrite some OpenZeppelin functions to provide support for tl;dr; This is an audited, EIP2612-referenced, version with better revert messages and much better test coverage. |
Technically, it should not matter which action is done first as if there is not enough allowance the transaction will revert. This is how OpenZeppelin contract is implemented. However, given that UnderwriterToken is based on an audited Uniswap LP contract code and that in the Uniswap contract, allowance is checked before transfer, it makes sense to keep the order aligned.
No more comments other than testing structure might change based on this thread. But also we can refactor it later. |
👍 on your rationale @pdyraga, |
Underwriter tokens represent an ownership share in the underlying
collateral of the asset-specific pool. Underwriter tokens are minted
when a user deposits ERC20 tokens into asset-specific pool and they are
burned when a user exits the position. Underwriter tokens natively
support meta transactions. Users can authorize a transfer of their
underwriter tokens with a signature conforming EIP712 standard,
rather than an on-chain transaction from their address just like in the
case of Uniswap LP or DAI token. Anyone can submit this signature
on the user's behalf by calling the permit function, as specified in
EIP2612 standard, paying gas fees, and possibly performing other
actions in the same transaction.
The implementation mostly mirrors UniswapV2ERC20 contract adding
some tweaks from OpenZeppelin ERC20 implementation such as
meaningful revert messages and Approval event emitted on calls to
transferFrom. This allows applications to reconstruct the allowance
for all accounts just by listening to said events. Other
implementations of the EIP may not emit these events, as it isn't
required by the specification and UniswapV2ERC20 is one of them.
Unit tests were based on OpenZeppelin ERC20 unit tests with our own
tests implementation for EIP2612 and EIP712 functions.
Last but not least, this token contract can be cloned using EIP1167
mechanism.