🇺🇲
Protocolink
  • 🔮Overview
  • 🌟Why Protocolink?
  • 💡Use Cases
    • Flash Loans
    • Permit2 Amplifier
    • Zap-in & Zap-out
    • Position Management
    • Multi-Action Bundling
  • 📋Networks & Protocols
  • 🛡️Security & Audits
  • 💎Fees
  • ❓FAQ
  • Protocolink API
    • 🔮Overview
      • Swap & Supply (Example)
    • 📗Swagger
      • Request Protocols
      • Request Tokens
      • Request Quote
      • Estimate Logics Result
      • Request Transaction Data
  • Protocolink SDK
    • 🔮Overview
    • 1️⃣Install SDK
    • 2️⃣Build Logics
    • 3️⃣Estimate Router Data
    • 4️⃣Send Router Transaction
    • ⚒️API SDK Interfaces
      • Global Types
      • FlashLoan Logic
      • Aave V2
      • Aave V3
      • Balancer V2
      • Compound V3
      • Iolend
      • Magicsea
      • Morphoblue
      • OpenOcean V2
      • ParaSwap V5
      • Permit2
      • Spark
      • Stargate
      • Stargate V2
      • SyncSwap
      • Uniswap V3
      • Utility
      • Wagmi
      • ZeroEx V4
    • ⚒️Common SDK Interfaces
      • Constants
      • Network
      • Token
      • Web3Toolkit
      • Utility Functions
  • Lending SDK
    • 🔮Overview
    • ✳️SDK
      • Open By Collateral
      • Open By Debt
      • Close
      • Leverage By Collateral
      • Leverage By Debt
      • Deleverage
      • Collateral swap
      • Debt swap
      • Zap supply
      • Zap withdraw
      • Zap repay
      • Zap borrow
  • Smart Contract
    • 🔮Overview
      • Router
      • Agent
      • Callback
      • Fees
      • Utility
      • Data Type
      • ERC721/ERC1155 Support
    • 📑Deployment Addresses
    • 🧑‍💻Security Review Details
  • COMPOUND KIT
    • 🔮Overview
    • ✳️SDK
      • Leverage
      • Deleverage
      • Collateral Swap
      • Zap Supply
      • Zap Withdraw
      • Zap Repay
      • Zap Borrow
    • 📗API
  • Video Tutorials
    • 1. Introducing Protocolink
    • 2. Lending SDK
    • 3. Protocolink Q&A
  • Social medias
    • Twitter
  • Support
Powered by GitBook
On this page
  • Execute Transactions
  • Create a New Agent
  • Grant Agent Permissions
  • Calculate Agent Address
  1. Smart Contract
  2. Overview

Agent

The execution unit of user transactions. The Agent securely holds token approvals for its exclusive user, and it is non-upgradable.

PreviousRouterNextCallback

Last updated 1 year ago

Execute Transactions

When an Agent is called by the Router, it receives the protocol operations specified in the logics. Since the token amount used in each operation has to be set before the execution, how do users know the precise value (say operation B consumes the return token of operation A) considering the fluctuating blockchain states? To solve this problem, Protocolink offers a mechanism called BalanceLink.

function _executeLogics(
    DataType.Logic[] calldata logics,
    bool chargeOnCallback
) internal {}

BalanceLink

BalanceLink allows users to set will-be-replaced token amounts in the data. To deal with the will-be-replaced token amount, the Agent reads the balanceBps and the amountOrOffset from the included in the logics:

  • The balanceBps is for the Agent to calculate the real amount with its token balance.

  • The amountOrOffset is used as the offset by the Agent to replace the will-be-replaced token amount from the data.

After replacing the token amount, the Agent is ready to execute the operation without knowing how many tokens it got from the prior operation.

If the token amount is sent via msg.value, the amountOrOffset needs to be specified as to skip the replacement.

BalanceLink also allows users to set fixed token amounts in the data directly. To help the Agent know the token amounts in the data do not need to be replaced, users need to set the balanceBps to 0 and the amountOrOffset to the corresponding fixed token amount. When the Agent finds the balanceBps value as zero, it executes the operation with the data directly.

Create a New Agent

In Protocolink, one Agent is dedicated to one user. When a user conducts the very first transaction, the Router checks whether the corresponding Agent exists. If the Agent does not exist, the Router creates a new one in the transaction, eliminating the need to create it in another transaction.

function _execute(
    address user,
    bytes[] calldata permit2Datas,
    DataType.Logic[] calldata logics,
    address[] calldata tokensReturn
) internal {
    IAgent agent = agents[user];

    if (address(agent) == address(0)) {
        agent = IAgent(_newAgent(user));
    }

    emit Executed(user, address(agent));
    agent.execute{value: msg.value}(permit2Datas, logics, tokensReturn);
}

When creating an Agent, the Router requires the user address as salt and saves the relation between the user and the Agent in the map. By having a dedicated Agent, users no longer need to worry about the risk of placing token approvals on a shared one.

function _newAgent(address user) internal returns (address) {
    IAgent agent = IAgent(address(new Agent{salt: bytes32(bytes20(user))}(agentImplementation)));
    agents[user] = agent;
    emit AgentCreated(address(agent), user);
    return address(agent);
}

Grant Agent Permissions

In certain scenarios, users must grant their Agent certain permissions, such as setting token allowances in Permit2 before sending transactions.

Calculate Agent Address

To grant permissions to the right Agent, users can use the calcAgent(address) function to obtain the Agent address before executing a transaction.

function calcAgent(address user) external view returns (address) {
    address result = address(
        uint160(
            uint256(
                keccak256(
                    abi.encodePacked(
                        bytes1(0xff),
                        address(this),
                        bytes32(bytes20(user)),
                        keccak256(abi.encodePacked(type(Agent).creationCode, abi.encode(agentImplementation)))
                    )
                )
            )
        )
    );
    return result;
}

This function utilizes the opcode. It requires a user address that is used to query the corresponding Agent address.

🔮
CREATE2
1<<255
Input