Skip to content

Instantly share code, notes, and snippets.

@m9800
Last active May 28, 2023 16:10
Show Gist options
  • Save m9800/b1925b259fa7dcd6febc22ebc730b324 to your computer and use it in GitHub Desktop.
Save m9800/b1925b259fa7dcd6febc22ebc730b324 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";


contract CrossChainWarriors is
    ERC721("CrossChainWarriors", "CCWAR"),
    CrossChainWarriorsErrors, Ownable
{
    using Counters for Counters.Counter;


    Counters.Counter public tokenIds;

    address public _validator;
    
    mapping(uint256 => address) addressByChainId;


    modifier onlyValidator(){
        require(_msgSender() == _validator,"Not a Validator");
        _;
    }


    event CrossChainTransfer(
        uint256 crossChainId,
        address contractAddress,
        bytes message
    );

    constructor(
        address validator  
    )  
    {
        _validator = validator;
        tokenIds.increment();
    }

    function mint(address to) public returns (uint256) {
        uint256 newWarriorId = tokenIds._value;
        _safeMint(to, newWarriorId);
        tokenIds.increment();

        return newWarriorId;
    }

    /**
     * @dev Useful for cross-chain minting
     */
    function _mintId(address to, uint256 tokenId) internal {
        _safeMint(to, tokenId);
    }

    function _burnWarrior(uint256 burnedWarriorId) internal {
        _burn(burnedWarriorId);
    }

    /**
     * @dev Cross-chain functions
     */

    function crossChainTransfer(
        uint256 crossChainId,
        address to,
        uint256 tokenId
    ) external {

        if (!_isApprovedOrOwner(_msgSender(), tokenId)) revert InvalidTransferCaller();
        _burnWarrior(tokenId);
        
        emit CrossChainTransfer(
            crossChainId,
            addressByChainId[crossChainId],
            abi.encode(tokenId, msg.sender, to)
        );
    }

    function crossChainMessage(bytes calldata message)
        external
        onlyValidator
    {
        (
            uint256 tokenId,
            ,
            address to
        ) = abi.decode(message, (uint256, address, address));

        _mintId(to, tokenId);
    }


    function addChainAddress(uint chainId, address contractAddress) external onlyValidator{
        addressByChainId[chainId] = contractAddress;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment