Skip to content

Smart Contracts - Standardize ERC20FeeProxy and EthereumFeeProxy platform fee behavior #1692

Description

@MantisClone

Problem

ERC20FeeProxy lacks a fee-from-total function that EthereumFeeProxy already has:

Contract Fee-from-total (payee bears fee) Fee-as-surplus (payer bears fee)
EthereumFeeProxy transferWithReferenceAndFee transferExactEthWithReferenceAndFee
ERC20FeeProxy missing transferFromWithReferenceAndFee

EthereumFeeProxy supports both modes:

// Fee-from-total (payee bears): fee deducted from msg.value
transferWithReferenceAndFee(to, ref, feeAmount, feeAddress)
// → payee receives msg.value - feeAmount

// Fee-as-surplus (payer bears): explicit amounts
transferExactEthWithReferenceAndFee(to, amount, ref, feeAmount, feeAddress)
// → payee receives amount, payer must provide amount + fee

ERC20FeeProxy only supports fee-as-surplus:

// Fee-as-surplus (payer bears): explicit amounts
transferFromWithReferenceAndFee(token, to, amount, ref, feeAmount, feeAddress)
// → payee receives amount, payer must provide amount + fee

This gap:

  1. Prevents contract-level support for payee-borne fees on ERC20 payments
  2. Creates interface inconsistency between ETH and ERC20 integrations

Proposed Solution

Add a fee-from-total function to ERC20FeeProxy:

function transferFromTotalWithReferenceAndFee(
    address _tokenAddress,
    address _to,
    uint256 _totalAmount,    // total to pull from payer
    bytes calldata _paymentReference,
    uint256 _feeAmount,
    address _feeAddress
) external {
    uint256 payeeAmount = _totalAmount - _feeAmount;
    safeTransferFrom(_tokenAddress, _to, payeeAmount);
    if (_feeAmount > 0 && _feeAddress \!= address(0)) {
        safeTransferFrom(_tokenAddress, _feeAddress, _feeAmount);
    }
    emit TransferWithReferenceAndFee(...);
}

This enables contract-level feeBearer:

  • Payer bears fee: Use existing transferFromWithReferenceAndFee (payer sends amount + fee)
  • Payee bears fee: Use new transferFromTotalWithReferenceAndFee (payer sends total, payee receives total - fee)

Scope

This is a major undertaking with ripple effects across the stack:

1. Smart Contract Changes

  • ERC20FeeProxy: Add transferFromTotalWithReferenceAndFee
  • BatchNoConversionPayments: Support new function
  • BatchConversionPayments: Support new function
  • Conversion proxies: Audit and update as needed
  • Other dependent contracts: Audit each

2. Contract Deployment

  • Deploy updated contracts to all supported chains
  • Old contract versions remain operational (backwards compatibility)
  • New deployments coexist with existing ones

3. SDK Changes

4. Payment Detection

  • Update detection logic for new function/events
  • Handle both old and new contract events

5. Payment Subgraph

  • Index new contract deployments (required regardless of event changes)
  • If event structure changes, update subgraph schema/mappings

6. Event Structure Decision

  • Decide whether to emit totalAmount or payeeAmount in event
  • This affects payment detection and subgraph

Considerations

  • Requires security audit for all contract changes
  • Backwards compatibility: old contracts remain operational, no migration required for existing requests

Related Issues

feeBearer without contract changes (can ship independently):

These implement feeBearer using payment calculation + balance interpretation with existing contracts. They work today without #1692.

What #1692 adds:
This issue enables on-chain events to potentially emit the total amount (via new function or modified event structure), providing full consistency for on-chain observers. Without #1692, on-chain events only show the net amount paid to payee.

References

  • ERC20FeeProxy: /packages/smart-contracts/src/contracts/ERC20FeeProxy.sol
  • EthereumFeeProxy: /packages/smart-contracts/src/contracts/EthereumFeeProxy.sol

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions