Solidity Conversion to Sway

Hi @Nazeeh21 @rishabhkeshan , can we able to connvert this solidity code functionalities as per fuel standard. Is it possible can you give some reference
thanks in advance

//SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.19;

import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./ISAGE1155.sol";

contract CricSageStore is
    Initializable,
    PausableUpgradeable,
    AccessControlUpgradeable,
    UUPSUpgradeable
{
    struct Order {
        address seller;
        address admin;
        address buyer;
        address asset;
        address paymentToken;
        uint256 tokenId;
        uint256 supply;
        uint256 price;
        uint256 expirationTime;
        uint256 salt;
        string questionId;
        string tokenURI;
        bool side;
    }

    struct Sign {
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    mapping(bytes32 => bool) public fills;
    mapping(address => bool) whitelistedAddress;
    bytes32 public constant SIGNER_ROLE = keccak256("SIGNER_ROLE");
    bytes32 public constant RELAYER_ROLE = keccak256("RELAYER_ROLE");

    event AddedToWhitelist(address erc20Address);
    event RemovedFromWhitelist(address erc20Address);
    event mintandBuyOrderExecuted(
        address nftAddress,
        address seller,
        address buyer,
        address paymentToken,
        uint256 tokenId,
        uint256 supply,
        uint256 price,
        string questionId,
        bool side,
        bytes32 hash
    );
    event OrderExecuted(
        address nftAddress,
        address seller,
        address buyer,
        address paymentToken,
        uint256 tokenId,
        uint256 supply,
        uint256 price,
        bytes32 hash
    );

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize(address signer, address admin) public initializer {
        _setupRole(DEFAULT_ADMIN_ROLE, admin);
        _setRoleAdmin(DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_ROLE);
        _setRoleAdmin(RELAYER_ROLE, DEFAULT_ADMIN_ROLE);
        _setupRole(SIGNER_ROLE, signer);
        _setRoleAdmin(SIGNER_ROLE, DEFAULT_ADMIN_ROLE);
    }

    function pause() external onlyRole(DEFAULT_ADMIN_ROLE) {
        _pause();
    }

    function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) {
        _unpause();
    }

    function addWhitelist(
        address erc20Address
    ) external onlyRole(DEFAULT_ADMIN_ROLE) returns (bool) {
        require(
            !whitelistedAddress[erc20Address],
            "Address is already whitelisted"
        );
        whitelistedAddress[erc20Address] = true;
        emit AddedToWhitelist(erc20Address);
        return true;
    }

    function removeWhitelist(
        address erc20Address
    ) external onlyRole(DEFAULT_ADMIN_ROLE) returns (bool) {
        require(whitelistedAddress[erc20Address], "Address is not whitelisted");
        whitelistedAddress[erc20Address] = false;
        emit RemovedFromWhitelist(erc20Address);
        return true;
    }

    function setRelayer(
        address[] memory accounts
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        for (uint256 i = 0; i < accounts.length; i++) {
            _grantRole(RELAYER_ROLE, accounts[i]);
        }
    }

    function executeOrderByRelayer(
        Order calldata order,
        Sign calldata sign
    ) external whenNotPaused onlyRole(RELAYER_ROLE) {
        bytes32 hash = hashOrder(order);
        require(isValidSignature(hash, sign), "Invalid sign");
        _executeOrder(order, hash);
    }

    function executeOrderByBuyer(
        Order calldata order,
        Sign calldata sign
    ) external whenNotPaused {
        require(order.buyer == msg.sender, "Buyer and sender should be same");
        bytes32 hash = hashOrder(order);
        require(isValidSignature(hash, sign), "Invalid sign");
        _executeOrder(order, hash);
    }

    function executeOrderByMintAndBuy(
        Order calldata order,
        Sign calldata sign
    ) external whenNotPaused {
        require(order.buyer == msg.sender, "Buyer and sender should be same");
        bytes32 hash = hashOrderPrimary(order);
        require(isValidSignature(hash, sign), "Invalid sign");
        _executeOrderByMint(order, hash);
    }

    function hashOrderPrimary(
        Order calldata order
    ) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    order.admin,
                    order.buyer,
                    order.asset,
                    order.paymentToken,
                    order.tokenId,
                    order.supply,
                    order.price,
                    order.expirationTime,
                    order.salt,
                    order.questionId,
                    order.side
                )
            );
    }

    function hashOrder(Order calldata order) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    order.seller,
                    order.buyer,
                    order.asset,
                    order.paymentToken,
                    order.tokenId,
                    order.supply,
                    order.price,
                    order.expirationTime,
                    order.salt
                )
            );
    }

    function hashMintAndExecuteOrder(
        address celebrityAddress,
        string memory tokenURI,
        Order calldata order
    ) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    celebrityAddress,
                    tokenURI,
                    order.seller,
                    order.buyer,
                    order.asset,
                    order.paymentToken,
                    order.tokenId,
                    order.supply,
                    order.price,
                    order.expirationTime,
                    order.salt
                )
            );
    }

    function recoverERC20(
        address token,
        address receiver
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        IERC20Upgradeable(token).transfer(
            receiver,
            IERC20Upgradeable(token).balanceOf(address(this))
        );
    }

    function _authorizeUpgrade(
        address newImplementation
    ) internal override onlyRole(DEFAULT_ADMIN_ROLE) {}

    function isValidSignature(
        bytes32 hash,
        Sign calldata sign
    ) internal view returns (bool) {
        address signer = ecrecover(
            keccak256(
                abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)
            ),
            sign.v,
            sign.r,
            sign.s
        );
        return hasRole(SIGNER_ROLE, signer);
    }

    function _executeOrder(Order calldata order, bytes32 hash) internal {
        require(
            whitelistedAddress[order.paymentToken],
            "Not whitelisted address"
        );
        require(!fills[hash], "Order already executed");
        require(
            order.expirationTime != 0 &&
                order.expirationTime >= block.timestamp,
            "Order Expired"
        );
        fills[hash] = true;
        IERC20Upgradeable(order.paymentToken).transferFrom(
            order.buyer,
            order.admin,
            order.price
        );

        ISAGE1155(order.asset).safeTransferFrom(
            order.seller,
            order.buyer,
            order.tokenId,
            order.supply,
            ""
        );

        emit OrderExecuted(
            order.asset,
            order.admin,
            order.buyer,
            order.paymentToken,
            order.tokenId,
            order.supply,
            order.price,
            hash
        );
    }

    function _executeOrderByMint(Order calldata order, bytes32 hash) internal {
        require(
            whitelistedAddress[order.paymentToken],
            "Not whitelisted address"
        );
        require(!fills[hash], "Order already executed");
        require(
            order.expirationTime != 0 &&
                order.expirationTime >= block.timestamp,
            "Order Expired"
        );
        fills[hash] = true;
        IERC20Upgradeable(order.paymentToken).transferFrom(
            order.buyer,
            order.admin,
            order.price
        );

        ISAGE1155(order.asset).safeMintSupply(
            order.buyer,
            order.tokenId,
            order.supply,
            order.questionId,
            order.side
        );

        emit mintandBuyOrderExecuted(
            order.asset,
            order.admin,
            order.buyer,
            order.paymentToken,
            order.tokenId,
            order.supply,
            order.price,
            order.questionId,
            order.side,
            hash
        );
    }
}

Hey @mahesh_d_luffy, you can use our transpiler that will help you convert your solidity contract to sway. It does not give bug free and production ready contract but it def helps to get the wheel going

2 Likes

okay thanks @Nazeeh21