# Contract Interface

### Contract Specification

Here’s what you need to implement to get started:

```solidity
interface ITAI {
  event BridgeLimitsSet(uint256 _mintingLimit, uint256 _burningLimit, address indexed _bridge);
  error IXERC20_NotHighEnoughLimits();

  struct BridgeParameters {
    uint256 timestamp;
    uint256 ratePerSecond;
    uint256 maxLimit;
    uint256 currentLimit;
  }

  struct Bridge {
    BridgeParameters minterParams;
    BridgeParameters burnerParams;
  }

  function setLimits(address _bridge, uint256 _mintingLimit, uint256 _burningLimit) external;
  function mintingMaxLimitOf(address _bridge) external view returns (uint256 _limit);
  function burningMaxLimitOf(address _bridge) external view returns (uint256 _limit);
  function mintingCurrentLimitOf(address _bridge) external view returns (uint256 _limit);
  function burningCurrentLimitOf(address _bridge) external view returns (uint256 _limit);
  function mint(address _user, uint256 _amount) external;
  function burn(address _user, uint256 _amount) external;
}
```

Requirements:

* `mint` should only proceed if the current limit is enough for the amount being minted, and it should reduce the limit accordingly.
* `burn` functions the same way, ensuring the limit is sufficient before proceeding and then reducing it.

All ICrosschainERC20 tokens should also support the standard ERC-20 functions but are not required to fully support ERC777.

**Example Implementation**

Here’s a basic contract setup:

```solidity
contract MyXERC20 is ICrosschainERC20 {
    struct BridgeParameters {
        uint256 timestamp;
        uint256 ratePerSecond;
        uint256 maxLimit;
        uint256 currentLimit;
    }

    struct Bridge {
        BridgeParameters minterParams;
        BridgeParameters burnerParams;
    }

    address public owner;
    mapping(address => Bridge) public bridges;

    event BridgeLimitsSet(uint256 mintingLimit, uint256 burningLimit, address indexed bridge);
    error IXERC20_NotHighEnoughLimits();

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this.");
        _;
    }

    modifier onlyBridge() {
        require(bridges[msg.sender].minterParams.maxLimit > 0, "Not a valid bridge.");
        _;
    }

    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        owner = msg.sender;
    }

    function setLimits(
        address _bridge,
        uint256 _mintingLimit,
        uint256 _burningLimit
    ) external onlyOwner {
        BridgeParameters storage params = bridges[_bridge].minterParams;
        params.maxLimit = _mintingLimit;
        params.currentLimit = _mintingLimit;
        params = bridges[_bridge].burnerParams;
        params.maxLimit = _burningLimit;
        params.currentLimit = _burningLimit;
        emit BridgeLimitsSet(_mintingLimit, _burningLimit, _bridge);
    }

    // Additional functions for viewing and updating limits, minting, and burning are defined similarly...
}
```


---

# 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.fabriq.network/universal-asset-issuance/contract-interface.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.
