# Implement an Action

Actions are custom smart contracts invoked by Tipn whenever a Like on Farcaster meets certain conditions.&#x20;

## The Interface

All Tipn Actions must inherit the following interface and implement the `onTip` function:

```
interface IAction {
    function onTip(
        address from, 
        address to, 
        address cast, 
        uint quantity, 
        bytes calldata data
    ) external;
}
```

The arguments passed to `onTip` are specified as follows:

{% columns %}
{% column width="16.666666666666664%" %}
**`from`**

**`to`**

**`cast`**

**`quantity`**

**`data`**
{% endcolumn %}

{% column %}
address tied to tipper’s FID

address tied to creator’s FID

hash the liked cast

USDC value (1 USDC = 1000000)

arbitrary data payload (custom)
{% endcolumn %}
{% endcolumns %}

The `data`  argument is a placeholder for any custom data that the action may needs to run. Customizing this requires coordination with the Tipn team to ensure the tip engine submits the relevant data to your contract.

## Example contract

Here is a demo Tipn Action that pools tips sent, and records the amounts sent by each user:

```
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract PoolAction is IAction, Ownable {

    address public constant TIPN = 0x10462E4b4d32dF88D2030E0CACD2BfBA40264BDF;
    IERC20 public constant USDC = IERC20(0x833589fcd6edb6e08f4c7c32d4f71b54bda02913);

    mapping(address => uint) public userTipTotal;
    
    // Conform to the IAction specification
    // This method is called on every tip. 
    function onTip(
        address from, 
        address to, 
        address cast, 
        uint quantity, 
        bytes calldata data
    ) external {
        // Ensure action is only callable by the Tipn contract
        require(msg.sender == TIPN, "Not Tipn");
        
        // Track the individual user tip totals
        userTipTotal[from] += quantity;
    }
    
    // Send the USDC to a custom recipient
    // Only callable by the owner of the contract
    function sendUSDC(
        address recipient
    ) external onlyOwner {
        uint balance = USDC.balanceOf(address(this));
        USDC.transfer(recipient, balance);
    }
}

```

Once your Tipn Action is implemented, the next step is to get it listed.
