The TwabERC20.sol contract implements ERC20Permit, this library provides permit functionality for ERC20s but is left behind by the new reliable permit() standard that many major protocols have migrated to. The issue is that the (v,r,s) permit() signature exists in the mempool and can be easily executed directly on the token contract while frontrunning the permit() transaction.
Although I am aware that this cannot happen when using permit in the vault contract (with depositWithPermit), I think that TwabERC20.sol is an independent contract and therefore permit() in TwabERC20.sol should be overridden with the recommended.
Lines of code
https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/TwabERC20.sol#L5 https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/TwabERC20.sol#L19 https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/TwabERC20.sol#L46 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/bd325d56b4c62c9c5c1aff048c37c6bb18ac0290/contracts/token/ERC20/extensions/ERC20Permit.sol#L49-L68
Vulnerability details
Impact
The
TwabERC20.sol
contract implementsERC20Permit
, this library provides permit functionality for ERC20s but is left behind by the new reliablepermit()
standard that many major protocols have migrated to. The issue is that the (v,r,s)permit()
signature exists in the mempool and can be easily executed directly on the token contract while frontrunning thepermit()
transaction.Although I am aware that this cannot happen when using permit in the vault contract (with
depositWithPermit
), I think thatTwabERC20.sol
is an independent contract and thereforepermit()
inTwabERC20.sol
should be overridden with the recommended.Proof of Concept
The inherited ERC20Permit's permit function:
For more information refer to the blog post on Trust Security's website.
Tools Used
Manual Review
Recommended Mitigation Steps
Use the
trustlessPermit()
variant here.Assessed type
ERC20