ERC777 Contract with ERC20 Tokens received

Hello guys.

Firstly I will explain what I would like to achieve. I need a contract which is allowing to receive only one specific ERC20 token (all other transactions should be rejected by the contract itself) and then that contract sends ETH token back to the sender.

Example: An address sends 10000 ERC20 X tokens to contract and contract sends back to sender 1 ETH.

I used an example code from this post

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC777/IERC777.sol";
import "@openzeppelin/contracts/introspection/IERC1820Registry.sol";
import "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";

/**
 * @title XToken777Recipient
 * @dev Very simple ERC777 Recipient
 */
contract XToken777Recipient is IERC777Recipient {

    IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
    bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");

    IERC777 private _token;

    event DoneStuff(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData);

    constructor (address token) {
        _token = IERC777(token); // Also tried with ERC20 and it didn't work

        _erc1820.setInterfaceImplementer(address(this), TOKENS_RECIPIENT_INTERFACE_HASH, address(this));
    }

    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external override {
        require(msg.sender == address(_token), "XToken777Recipient: Invalid token");

        // do stuff
        emit DoneStuff(operator, from, to, amount, userData, operatorData);
    }
}

Is the “address token” parameter in the constructor the address of my “X Token” that i am sending to the contract?
No matter which token I send, the tokensReceived function is never triggered. For start I just want to achieve that tokensReceived function is triggered and then I will add other functions to send ETH back to sender.

I would like to know how the tokenReceived hook is triggered. Is it automatically triggered when transactions happens or do I need to call it somehow?

I am testing it on rinkeby testnet network. Maybe this hook doesn’t work properly on rinkeby testnet? Any suggestions for a specific network I should use?

Thank you in advance.

Regards

Hi, welcome! :wave:

I think you can have a look at this tutorial

Hi,

thank you for your reply. I linked the same post as you did which i have used it as a tutorial.

So if I add revert function inside of tokensReceived function all transactions should be reverted? I tried this and all transactions are confirmed. I don’t know what exactly am i doing wrong that tokensReceived is not triggered.

function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external override {
        revert();
        // require(msg.sender == address(_token), "XToken777Recipient: Invalid token");

        // do stuff
        // emit DoneStuff(operator, from, to, amount, userData, operatorData);
    }