> For the complete documentation index, see [llms.txt](https://docs.openliq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openliq.com/openliq-aggregator-specs/fees/collect-fees.md).

# Collect Fees

### **Fee Receiver Contract**

Each time a user swaps, the handling fee is directly transferred to the contract. And the preset users can withdraw fees from the contract.

#### Preset the Payee for fee withdrawl

The admin can add payee and set the corresponding withdrawal propotion in the contract; Payees can only withdraw tokens from the contract according to their preset propotions.&#x20;

The payee addresses and their corresponding shares are set in the constructor function

```solidity
constructor(address[] memory payees, uint256[] memory shares_,address _owner){
        require(payees.length == shares_.length, "payees and shares length mismatch");
        require(payees.length > 0, "no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
        require(_owner != address(0), "owner can not be zero address");
        _transferOwnership(_owner);
        converters[_owner] = true;
    }
```

#### Covert fee token to stablecoins

The contract contains a 'Convert' interface for converting tokens in the contract to stablecoins like USDT or USDC.

**Convert structure** is a key component for a convert transaction. It contains four fields, see below code blocks for detailed information.

```solidity
struct Convert {
 address token; //the fee token contract address that will be converted
 address callTo; // the DEX/SWAP contract address that is used for converting
 address approveode; //an contract address belongs DEX/SWAP that user should grant approval
 bytes payload; // the actual token swap calldata for later execution
}
```

The **convertToStablecoin** function is responsible for executing the transaction to swap fee tokens to stablecoin

```solidity
function convertToStablecoin(Convert[] calldata converts) external {
        require(converters[msg.sender],"convert deny");
        require(converts.length > 0);
        for(uint256 i = 0; i < converts.length; i++){
            require(converts[i].callTo.code.length > 0,"execute must be contract address");
            require(!stablecoins[converts[i].token],"not need convert");
            uint256 balance = Helper._getBalance(converts[i].token,address(this));
            bool result;
            if(Helper._isNative(converts[i].token)){
               (result,) = converts[i].callTo.call{value:balance}(converts[i].playload);
            } else {
                SafeERC20.safeIncreaseAllowance(IERC20(converts[i].token),converts[i].approveTo,balance);
                (result,) = converts[i].callTo.call(converts[i].playload);
            }
            require(result,"convert fail");
            emit ConvertTo(converts[i].token,balance);
        }
    }

```

#### Claim the converted stablecoin

All the preset payee addresses can claim their generated fees as stablecoins via **release** function

```solidity
function release(address token, address account) public virtual {
        require(shares[account] > 0, "account has no shares");
        require(stablecoins[token],"unsuport release token");
        uint256 payment = releasable(token, account);
        require(payment != 0, "account is not due payment");

        totalReleased[token] += payment;
        unchecked {
            payeeReleased[token][account] += payment;
        }
        Helper._transfer(token,account,payment);
        emit PaymentReleased(token, account, payment);
    }
```
