IPcl.runOnPcl

runOnPcl(address contractAddress, bytes calldata data, uint256 value) external returns (bytes memory)

Executes a call to a target contract within the PCL's regulated context. This function is the entry point to the 'Regulated Track'. It first triggers all applicable global and contract-specific policy checks based on the sender, target contract, and call data. If all checks pass, it then executes the provided call data on the target contract using a low-level call. If any check fails, the transaction reverts with a specific error.

Parameters

Name Type Required Description
contractAddress address The address of the target contract to call after PCL checks pass.
data bytes The ABI-encoded calldata for the function to be executed on the target contract.
value uint256 Amount in aokrw (base units, 18 decimals) to forward with the call — becomes msg.value on the target.

Returns

Type: bytes memory

The return data from the successful execution of the target contract call.

Errors

Code Name Description
InDenylist InDenylist Reverts if the sender's address is found in an active denylist policy.
EasAttestationRequired EasAttestationRequired Reverts if the sender lacks a required EAS attestation (e.g., for KYC).
VolumeAboveMaxLimit VolumeAboveMaxLimit Reverts if the transaction amount exceeds a configured volume limit.

Examples

Wrapping an ERC20 Transfer

This example shows a token contract that overrides its public transfer function. Instead of executing the logic directly, it calls runOnPcl, targeting itself (address(this)) and providing the encoded calldata for its own internal transfer logic. This ensures no transfer can occur without passing the PCL checks registered for this token.

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IPcl } from "@maroo-chain/contracts/IPcl.sol";

contract CompliantToken is IERC20 {
    IPcl constant PCL = IPcl(0x1000000000000000000000000000000000000005);
    // ... other ERC20 implementation ...

    function _transfer(address from, address to, uint256 amount) internal {
        // ... core transfer logic ...
    }

    // Public transfer function enforces PCL checks
    function transfer(address to, uint256 amount) public override returns (bool) {
        bytes memory data = abi.encodeWithSelector(
            this._transfer.selector,
            msg.sender,
            to,
            amount
        );

        // Execute via PCL — this contract calls itself through the PCL gate.
        PCL.runOnPcl(address(this), data, 0);
        return true;
    }
}

Calling another contract with error handling

This example demonstrates how to use a try/catch block to handle potential reversions from runOnPcl. It specifically checks for the InDenylist custom error and provides a more user-friendly message.

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;

import { IPcl } from "@maroo-chain/contracts/IPcl.sol";

contract PclCaller {
    IPcl constant PCL = IPcl(0x1000000000000000000000000000000000000005);

    function callCompliantService(address service, uint256 value) external {
        bytes memory data = abi.encodeWithSignature("deposit(uint256)", value);

        try PCL.runOnPcl(service, data, 0) returns (bytes memory) {
            // Success path
        } catch (bytes memory reason) {
            // bytes memory slicing isn't supported in Solidity — read the
            // 4-byte error selector via assembly.
            bytes4 selector;
            assembly { selector := mload(add(reason, 32)) }

            if (selector == IPcl.InDenylist.selector) {
                // Strip the selector and decode the arg.
                bytes memory args = new bytes(reason.length - 4);
                for (uint i = 0; i < args.length; i++) args[i] = reason[i + 4];
                address sender = abi.decode(args, (address));
                revert("Caller is on the denylist");
            }
            // Bubble up unknown reverts.
            revert(string(reason));
        }
    }
}
ESC
Type to search