# Fees

This page explains the fee mechanism in the Protocolink contracts. The overview fee structure can be found at [Fees](/fees.md#fee-structure).

Protocolink calculates the fees on-chain or off-chain depending on the user called function. When users call the Protocolink contract directly (e.g., [Router](/smart-contract/overview/router.md#execute-transactions)), Protocolink calculates the fees on-chain. When users call the Protocolink contract with API data (e.g., [Router](/smart-contract/overview/router.md#execute-transactions-with-api-data)), Protocolink charges the off-chain fee.

### On-Chain Fee

If users call the Router contract without the API data, Protocolink will calculate and charge the on-chain fee in the `execute()` function. The on-chain fee is charged from the token amounts transferred in the transaction. For ERC-20 tokens, the on-chain fee is charged in the [`_doPermit2()`](https://github.com/dinngo/protocolink-contract/blob/4b765ea9da53fc02b4bce890676cf080206fd00e/src/AgentImplementation.sol#L138) function, and for native tokens, the on-chain fee is charged in the [`_chargeByMsgValue()`](https://github.com/dinngo/protocolink-contract/blob/4b765ea9da53fc02b4bce890676cf080206fd00e/src/AgentImplementation.sol#L293) function. Protocolink charges the fee from the Agent.

```solidity
function execute(
    bytes[] calldata permit2Datas,
    DataType.Logic[] calldata logics,
    address[] calldata tokensReturn
) external payable {
    if (msg.sender != router) revert NotRouter();
    _doPermit2(permit2Datas, true);
    _chargeByMsgValue();
    _executeLogics(logics, true);
    _returnTokens(tokensReturn);
}
```

Protocolink also charges the flash loan fee before returning the control flow back to flash loan services. You can find out more details in the [AaveV3FlashloanCallback](https://github.com/dinngo/protocolink-contract/blob/c8743edc492bf7a25bbc8a0f55befb148e687a38/src/callbacks/AaveV3FlashLoanCallback.sol#L73C23-L73C23).

### Off-Chain Fee

If users call the Router contract with API data, Protocolink will charge the off-chain fee in the `executeWithSignerFee()` function. The fees are calculated in Protocolink's API server off-chain and are charged by token types. If the token is an ERC-20 token, the fee is charged from the user address. If the token is a native token, the fee is charged from the Agent address.

```solidity
function executeWithSignerFee(
    bytes[] calldata permit2Datas,
    DataType.Logic[] calldata logics,
    DataType.Fee[] calldata fees,
    bytes32[] calldata referrals,
    address[] calldata tokensReturn
) external payable {
    if (msg.sender != router) revert NotRouter();
    _doPermit2(permit2Datas, false);
    for (uint256 i; i < referrals.length; ) {
        _charge(fees, referrals[i], false);
        unchecked {
            ++i;
        }
    }
    _executeLogics(logics, false);
    _returnTokens(tokensReturn);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.protocolink.com/smart-contract/overview/fees.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
