[Audit] Revised Payment Order Struct#703
Conversation
* chore: adds notes md * chore: adapts PP Simple * chore: adapts PP Streaming * tmp * chore: adapts recurring pc * chore: adapts staking lm * chore: adapts payment router * chore: compiles * fix: `ERC20PaymentClientBaseV1Test > testAddPaymentOrders` * fix: `ERC20PaymentClientBaseV1Test > testAddPaymentOrder` * fix: `PP_SimpleV1Test` > `test_ValidPaymentOrder` * fix: `PP_StreamingV1Test` > `test_processPayments` * fix: `PP_StreamingV1Test` * chore: removes console logs * fix: `LM_PC_RecurringPayments_v1` * fix: `LM_PC_Staking_v1Test` * chore: fix outstanding tests * fix: event in pp template * chore: removes todo * chore: cleanup I * fix: always sets cliff flag in payment router * chore: cleanup II * chore: fix commented tests * chore: cleanup III * chore: adds default values to streaming pp * chore: renames `original_` => `exposed_` * chore: uses internal setters for default vals * chore: sets flags manually in recurring payments * chore: adds validation for stream time config * chore: fmt * chore: turn state vars private * chore: getter functions in staking and kpi module * chore: adapt state vars to coding standards * chore: adds internal validator fn for staking module * chore: make fmt * chore: shift flags by one * chore: fmt * Feat: Add Wrapper for Mint and Transfer Functions * Make the issue tokens functionality abstract * Adapt all inherited contracts * Revert Mock override Shouldnt have done that in the first place * Adapt Tests * Rename issueTokens to distributeIssuanceToken * Make distribute collateral functionality abstract * Rename parameter * Make naming uniform * Adapt all inherited contracts * adapt spelling mistake * Adapt tests * Cleanup * Fix test * Address Comments: Natspec * Cleanup * Rename _distributeIssuanceToken to _handleIssuanceTokenAfterBuy * Rename _distributeCollateralToken to _handleCollateralTokenAfterSell * Update FM_BC_Bancor_Redeeming_VirtualSupply_v1.sol * Update BondingCurveBase_v1.sol * Update Sections * Rename Function * Adapt sections in mocks * rename _handleIssuanceTokenAfterBuy * Update comments * Rename to _collateralTokenAmount * Update src/modules/fundingManager/bondingCurve/abstracts/BondingCurveBase_v1.sol Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> * Rename _issuanceMintAmount * Update src/modules/fundingManager/bondingCurve/abstracts/RedeemingBondingCurveBase_v1.sol Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> * Adapt version --------- Co-authored-by: Marvin <43185740+Zitzak@users.noreply.github.com> Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> * Sc 848 task copy fee adaption from topos to dev (#700) * Abstract projectFeeCollected * Create tests * Adapt emit test * convert flags to bytes32 * setter for default times in Streaming_PP + tests * test bugfix * refactor flags into PaymentClientBase * Adaptations to repo CoC * more CoC update * even more CoC * Update tests * Explainer text * refactor IERC20PaymentClientBase errors + bugfix * abstract functions out + update tests * address review comments * add init tests to inheritng modules * typo fix * Apply comment suggestions from code review Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> * adapt access mock function naming * Adapt naming of internal variable * Adapt comments * Adapt function naming * Fmt * Copy over lib subprojects from dev * Update src/modules/logicModule/LM_PC_RecurringPayments_v1.sol Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> --------- Co-authored-by: Felix Hieser <47272854+FHieser@users.noreply.github.com> Co-authored-by: Marvin <43185740+Zitzak@users.noreply.github.com> Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> Co-authored-by: 0xNuggan <82726722+0xNuggan@users.noreply.github.com> Co-authored-by: FHieser <felix_hieser@web.de>
src/modules/logicModule/abstracts/ERC20PaymentClientBase_v1.sol
Outdated
Show resolved
Hide resolved
| uint dataIdx = 0; | ||
|
|
||
| bool hasStart = (uint(flags) & (1 << 1)) != 0; | ||
| start = hasStart ? uint(data[dataIdx]) : defaultStart; |
There was a problem hiding this comment.
If default start and end are 0 you may want to have them as block.timestamp, it seems like this option could be useful as you would usually want the default to be whatever block.timestamp is, not a specific date.
There was a problem hiding this comment.
Thanks fo the tip! While it makes sense, we've chosen to go against it since being able to default variables to 0 (and therefore create valid payment Orders, even if they are immediately claimable), seems to me better than introducing block.timestamp values that the user might not expect.
I've created a linear issue to track this, in case we choose to look for a different way to handle it.
| /* | ||
| | Flag | Name | Disclaimer | | ||
| |------|------------|-----------------------------------------------------| | ||
| | 0 | orderID | The order id should be a hashed value of an | |
There was a problem hiding this comment.
It's missing the comment update merged into dev, which reverted this comment. We prob need to rebase/merge from dev.
Just something I noticed while working on another branch
There was a problem hiding this comment.
Yes, good reminder: please rebase from dev so this is up to date. I can also do this if you want (@0xNuggan) - lmk!
marvinkruse
left a comment
There was a problem hiding this comment.
Thank you for adressing my overall comment of the data array ordering thing I mentioned, to me it looks like that was fully addressed. We probably just need to make sure that each payment processor does it like you did it here (i.e. applies the same principle). May be worth to look into creating a library or a base here for payment processors that handles this?
|
Tagging @0xNuggan - as this is my PR I can't explicitly tag my comments as requests for changes, so just letting you know via this comment that I submitted my review. Feel free to close any comments that you feel like you properly addressed and just leave anything open you feel like I should look at again/you have comments on/etc. |
|
Thanks for the review! Addressed the comments |
|
About moving the array logic into a library I agree, but I can't think of a good place right now where we shoudl put it. But worth keeping in mind. |
marvinkruse
left a comment
There was a problem hiding this comment.
Looks good, just small typos.
The RPC fork test where we use Sepolia as not working anymore.
src/modules/logicModule/abstracts/ERC20PaymentClientBase_v1.sol
Outdated
Show resolved
Hide resolved
src/modules/logicModule/abstracts/ERC20PaymentClientBase_v1.sol
Outdated
Show resolved
Hide resolved
| } | ||
| if (orderBit == false && processorBit == true) { | ||
| // the P_P needs the value, but it's missing in the order | ||
| // ==> use default value |
There was a problem hiding this comment.
Would it not be better (safer) if this is an error? This after all is not a case where the order does not provide a value, it is a case where the "order type" is different from what is expected (I mean that if the flag value is different, this is not the same as providing a "0" value and have the PP fill that in with a default value)
For example, if the order says "This is an order with no start and end date", then it is it is better that a PP that is made for streaming orders says "Ok, you probably made a istake sending me this order" rather than have it say "O, ok, then I will just make it a streaming order which starts in 17 days and lasts 189 hours"
There was a problem hiding this comment.
It's intended behavior, since we want to give the PaymentProcessor to build a valid PaymentOrder using its defaults. I've added a check that the resulting PaymentOrder after "reconstruction" is valid.
…ders * Refactor BuyFor * Refactor SellOrder * Apply suggestions from code review Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com> --------- Co-authored-by: Marvin Kruse <marvinkruse@users.noreply.github.com>
|
Closing this in favor or #717 |
This PR contains changes related to our revised Payment Order Struct. A payment order is a formalized set of information used by payment clients and are sent to a payment processor, who acts based upon the information contained in the order.
What have we done
We revamped the struct and made a distinction between base information (i.e. amount, token, chainId, etc.) and additional information, where we saw that the additional information needs to allow for certain changes over time. We ultimately arrived at this struct:
The way the
flagsanddatafields work is as follows:The
flagsfield encodes which information is contained in thedataarray. The way this happens is similar to a bit-mask, where each of the bits in thebytes32variable represents one potential data type. We currently have these slots defined:So in this example, if we want to make use of the streamed payment processor and want to encode the
start,cliff, andendtimes, we would set theflagsvalue to be0000 [...] 0000 1110, so the flags at position 1, 2 and 3 and set to 1, while the rest is set to 0. If the used payment processor allows forstart,cliff, andendvalues, it will check whether these slots are set (i.e. are 1) and - if that is the case - extract these values from the array.The data array only contains values for slots where the flag is 1, so for the example above (
0000 [...] 0000 1110) it would contain three data entries (length of 3), where the first one is from flag 1 and so on.The documentation around this and the definition of the available slots can be found in
IERC20PaymentClientBase_v1.sol.