Skip to content

Conversation

@cwsnt
Copy link
Collaborator

@cwsnt cwsnt commented Jun 14, 2024

No description provided.

@cwsnt cwsnt requested a review from tjcloa June 14, 2024 23:21
@cwsnt cwsnt changed the title Feat: Fee sharing collector with direct transfer SOV-4106 Feat: Fee sharing collector with direct transfer Jun 24, 2024
*/
bytes32 payoutKey = keccak256(abi.encode(recv, token));
userBals_[payoutKey].surplusCollateral_ += collected;
require(userBals_[payoutKey].surplusCollateral_ <= type(uint96).max, "Value exceeds uint96 range");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really related to this change, but uint96 can theoretically overflow with something like POWA (where the total potential supply is 1 000 000 000 000 tokens with 18 decimals, or 1e30. uint96 max value is only around ~7.9e28)

Copy link
Contributor

@tjcloa tjcloa Jun 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch
this is the FeeSharingCollector contract's limit.
on the one hand - yes, it is technically possible to collect 1B, but in fact the fees are much less, practical max we had is 0.5%, so it is reduced down to 5e27 and only in case when the total supply is swapped which i doubt is practical.
i think we should restrict tokens with more than 18 deciamls and total supply <= 1B (trillion) for pools creation.
in case we ever reach the limit, we will upgrade (replace) the fee sharing collector.

Copy link

@koirikivi koirikivi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment about uint96, not related to this change really.

Copy link
Contributor

@tjcloa tjcloa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline comments

(, address treasury) = abi.decode(cmd, (uint8, address));

require(treasury != address(0) && treasury.code.length != 0, "Treasury invalid");
treasury_ = treasury;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to keep it universal i suggest to restore the original code

treasuryStartTime_ = uint64(block.timestamp + 7 days);

but replace 7 days with a constant TREASURY_START_TIME_OFFSET to have this option if needed on other chains.
The BOB and default implementation should have it set to 0.

import '../libraries/Encoding.sol';
import '../libraries/TokenFlow.sol';
import '../libraries/PriceGrid.sol';
import '../libraries/ProtocolCmd.sol';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need it here?


import "../libraries/PoolSpecs.sol";

interface ISdexQuery {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this interface is not used anywhere

@@ -0,0 +1,3 @@
# SdexConvertLib
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no SdexConvertLib
do you want to keep this README.md?

* @param recv - The receiver of the protocol fees.
* @param token - The token address of the quote token. */
* @param token - The token address of the quote token.
* @return withdrawn tokens */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in doesn't return anything

it("successfully collect treasury without time delay", async() => {
await test.testRevisePool(feeRate, 128, 1) // Turn on protocol fee
await pool.connect(await test.auth).protocolCmd(test.COLD_PROXY, transferCmd(policy.address), true)
await pool.connect(await test.auth).protocolCmd(test.COLD_PROXY, transferCmd(policy2.address), true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is policy replaced with policy2 here?

/**
* directly deposit token to fee protocol collector
*/
bytes32 payoutKey = keccak256(abi.encode(recv, token));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a constant PROTOCOL_FEES_RECEIVER_HASH - hash of 'PROTOCOL_FEES_RECEIVER' + some nonce - can be a hardcoded hash and use instead of recv because should we replace the FeeSharingCollector, the fees collected should be paid out to the new FSC, otherwise this portion will stuck or we would need to call from the previous FSC which is tricky - need not to forget to do it. once replaced - we should only transfer all the fees to he new FSC - one time operation.

Suggested change
bytes32 payoutKey = keccak256(abi.encode(recv, token));
bytes32 payoutKey = keccak256(abi.encode(PROTOCOL_FEES_RECEIVER_HASH, token));

* @param token - The token address of the quote token. */
* @param token - The token address of the quote token.
* @return withdrawn tokens */
function disburseProtocolFees (address recv, address token) internal {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need a receiver (recv) here. also see comments below for clarity.
tokens should be an array

Suggested change
function disburseProtocolFees (address recv, address token) internal {
function disburseProtocolFees (address[] tokens) internal {


import '../interfaces/IFeeProtocolCollector.sol';

/* @title Protocol Account Mixin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ProtocolAccount contract is inherited in WarmPath, but seems not to be used there.
pls double check and remove the inheritance.
the contract doesn't have it own storage, so should be safe.

bytes32 payoutKey = keccak256(abi.encode(recv, token));
userBals_[payoutKey].surplusCollateral_ += collected;
require(userBals_[payoutKey].surplusCollateral_ <= type(uint96).max, "Value exceeds uint96 range");
IFeeProtocolCollector(treasury_).transferTokens(token, uint96(userBals_[payoutKey].surplusCollateral_));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. FeeSharingCollector requires tokens approval for ERC20 tokens which is missing here.
    1.2 For the native token the function should be called with value payload.
  2. pls add tests - would have helped to discover it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants