Address courier front-running and persistent allowances #216
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Addresses
The reports above boil down to two points:
allowance
mapping to authorizecourierId
writes, the allowed entity also has control over some quantity of user shares. If users approve a single unit,1
, as intended, this isn't a big deal, but mistakes are possible.courierId
can only be written if the user's balance is precisely 0, so someone could frontrun a user's first deposit to prevent it from being set.In f27a6b9, I implemented two fixes:
courierId
writescourierId
to be set (from zero to non-zero) even if the user's balance is non-zeroTo make that second fix possible, we need the user's principle. This can be done by changing
_mint
and_burn
to track everyone's principle (even if they don't yet have a courier), OR by backfilling the empty principle with_convertToAssets(balance, inventory, totalSupply)
. Though I implemented the first option, neither is perfect. In the first, couriers receive a cut of all interest, including interest that accrued before they were credited. This feels wrong and users would not expect it. In the second,principle
loses its semantic meaning, since the back-filled value may be greater than the sum of all the user's deposited amounts. Even casting these problems aside, the "fix" is a rather large change and increases complexity.For these reasons, I switched to something simpler: