BNB Chain

0xda43dd736dd2a1183c36a1a56c5665a63c135568

Decompiled Solidity recovered from this contract's runtime bytecode. Best-effort reconstruction — confirm behaviour against on-chain state.

Decompilation outputBNB Chain · 0xda43dd733c1355684.5 KB4.2 s
Share
//decompiled by exvvul decompiler tool contact@exvul.com https://x.com/exvulsec
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

interface IDesolexERC20 {
    function transfer(address recipient, uint256 amount) external returns (bool success);
}

contract DesolexContract {
    uint256 public constant DEFAULT_ADMIN_ROLE = 0;
    
    mapping(bytes32 => mapping(address => bool)) public hasRole; // STORAGE[0x0]
    mapping(bytes32 => uint256) public getRoleMemberCount; // STORAGE[0x1]
    address public BTCX; // STORAGE[0x2]
    address public signAddress; // STORAGE[0x3]
    address public withdrawAddress; // STORAGE[0x4]
    address public fundAddress; // STORAGE[0x5]
    mapping(uint256 => address) public withdrawInfo; // STORAGE[0x6]
    uint256 public DOMAIN_SEPARATOR; // STORAGE[0x7]
    mapping(address => bytes32) mapping_expr_aa;
    mapping(bytes32 => uint256) mapping_expr_ah;
    mapping(address => bytes32) mapping_expr_ap;
    mapping(address => bytes32) mapping_expr_m;
    mapping(address => uint256) mapping_expr_s;
    uint256 stor_expr_ac;
    address stor_expr_ad;
    bytes32 stor_expr_ag;
    uint256 stor_expr_ak;
    bytes32 stor_expr_al;
    bytes32 stor_expr_am;
    bytes32 stor_expr_ao;
    bytes32 stor_expr_g;
    bytes32 stor_expr_h;
    address stor_expr_o;
    uint256 stor_expr_v;
    bytes32 stor_expr_w;
    bytes32 stor_expr_x;
    bytes32 stor_expr_z;
    
    event RoleRevoked(bytes32 indexed, address indexed, address indexed);
    event Withdrawinfo(address indexed, uint256 indexed, uint256 indexed);
    event RoleGranted(bytes32 indexed, address indexed, address indexed);
    function _desolexPanic(uint256 code) private pure {
        assembly ("memory-safe") {
            mstore(0x00, shl(224, 0x4e487b71))
            mstore(0x04, code)
            revert(0x00, 0x24)
        }
    }
    fallback() external payable {
        // Synthetic compatibility routes preserve original selectors for unresolved names.
        if ((msg.data.length >= 4) && (msg.sig == 0x4a28d784)) {
            // Route to Unknown_4a28d784(uint256,uint256,uint256,bool,uint256,uint256,bytes32,bool,uint256,uint256) after replacing only msg.sig.
            __desolexSelectorShim(uint32(0xe87d7864));
            return;
        }
        if ((msg.data.length >= 4) && (msg.sig == 0x9010d07c)) {
            // Route to Unknown_9010d07c(uint256,uint256) after replacing only msg.sig.
            __desolexSelectorShim(uint32(0xb656a175));
            return;
        }
        revert();
    }
    
    
    function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
        require(interfaceId == (interfaceId & 0xffffffff00000000000000000000000000000000000000000000000000000000));
        if (0x5a05180f00000000000000000000000000000000000000000000000000000000 == (interfaceId & 0xffffffff00000000000000000000000000000000000000000000000000000000)) {
            return !(!(0x5a05180f00000000000000000000000000000000000000000000000000000000 == (interfaceId & (0xffffffff00000000000000000000000000000000000000000000000000000000))));
        } else {
            if (0x7965db0b00000000000000000000000000000000000000000000000000000000 == (interfaceId & 0xffffffff00000000000000000000000000000000000000000000000000000000)) {
                return !(!(0x7965db0b00000000000000000000000000000000000000000000000000000000 == (interfaceId & (0xffffffff00000000000000000000000000000000000000000000000000000000))));
            } else {
                return !(!(interfaceId & (0xffffffff00000000000000000000000000000000000000000000000000000000) == 0x01ffc9a700000000000000000000000000000000000000000000000000000000));
            }
        }
    }
    
    function setConfig(address arg0, address arg1, address arg2, address arg3) public payable {
        require(bytes1(hasRole[0][msg.sender]) != 0x0, "error");
        BTCX = arg0;
        signAddress = arg1;
        withdrawAddress = arg2;
        fundAddress = arg3;
    }
    
    function getRoleAdmin(bytes32 role) public view returns (uint256) {
        return stor_expr_g;
    }
    
    function grantRole(bytes32 role, address account) public payable {
        internal_37e(account, role);
    }
    
    function admin(address recipient, address token, uint256 amount) public payable {
        require(bytes1(hasRole[0][msg.sender]) != 0x0, "error");
        IDesolexERC20(token).transfer(recipient, amount);
    }
    
    function renounceRole(bytes32 role, address account) public payable {
        require(msg.sender == account, "AccessControl: can only renounce roles for self");
        if (bytes1(hasRole[role][account])) {
            hasRole[role][account] = false;
            emit RoleRevoked(role, account, msg.sender);
        }
        if (mapping_expr_s[account] != 0) {
            if (!((getRoleMemberCount[role] - 0x01) == (mapping_expr_s[account] - 0x01))) {
                if (!((getRoleMemberCount[role] - 0x01) < stor_expr_v)) _desolexPanic(50);
                if (!((mapping_expr_s[account] - 0x01) < stor_expr_v)) _desolexPanic(50);
                stor_expr_w = stor_expr_x;
                mapping_expr_s[stor_expr_x] = mapping_expr_s[account];
            }
            if (!(getRoleMemberCount[role] != 0x0)) _desolexPanic(49);
            stor_expr_z = 0;
            getRoleMemberCount[role] = getRoleMemberCount[role] - 0x01;
            mapping_expr_aa[account] = 0;
        }
    }
    
    function Unknown_4a28d784(uint256 arg0, uint256 arg1, uint256 amount, bool arg3, uint256 arg4, uint256 arg5, bytes32 arg6, bool arg7, uint256 arg8, uint256 arg9) public payable {
        require(arg3 == (arg3 & 0xff));
        require(arg7 == (arg7 & 0xff));
        require(arg0 > 0x0, "id error");
        var_b = 0x06;
        require(!(withdrawInfo[arg0]), " id withdraw error");
        var_j = (0xe0 + var_j) + 0x20;
        require(var_b);
        require(address(var_q) != 0x0, "invalid signature");
        require(signAddress == (address(var_q)), "unauthorized");
        withdrawInfo[arg0] = (msg.sender) | (0xffffffffffffffffffffffff0000000000000000000000000000000000000000 & withdrawInfo[arg0]);
        require(withdrawAddress.code.length != 0x0);
        (bool success0, bytes memory returnData0) = withdrawAddress.withdraw(arg0, BTCX, arg1, bytes1(arg3), arg4, arg5, arg6); // call
        require(success0);
        IDesolexERC20(BTCX).transfer(fundAddress, amount);
        IDesolexERC20(BTCX).transfer(msg.sender, arg1 - amount);
        emit Withdrawinfo(msg.sender, arg0, arg1);
    }
    
    function Unknown_9010d07c(uint256 arg0, uint256 arg1) public view returns (address) {
        if (!(arg1 < stor_expr_ac)) _desolexPanic(50);
        return stor_expr_ad;
    }
    
    function revokeRole(bytes32 role, address account) public payable {
        internal_86d(account, role);
    }
    
    function internal_37e(address account, bytes32 role) private {
        // Decompilation incomplete: helper effect provenance is conservative.
        if (!(bytes1(hasRole[stor_expr_h][msg.sender]) != 0x0)) {
            if (!(0x14 * 0x2 + 0x2 <= 0xffffffffffffffff)) _desolexPanic(65);
            uint256 var_d;
            var_d = var_d + (0x20 + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 & (0x1f + ((0x14 * 0x02) + 0x02))));
            uint256 value0 = (0x14 * 0x02) + 0x02;
            if (0x14 * 0x2 + 0x2 != 0x0) {
                value0 = ((0x14 * 0x02) + 0x02) + (var_d + 0x20);
            }
            if (!(0 < var_d.length)) _desolexPanic(50);
            if (!(0x01 < var_d.length)) _desolexPanic(50);
            uint256 value1 = (0x14 * 0x02) + 0x01;
            uint256 value2 = msg.sender;
            uint256 value4;
            while (true) {
                uint256 value3 = value1;
                value4 = value2;
                if (value1 <= 0x1) {
                    break;
                }
                if (!((0xf & value2) < 0x10)) _desolexPanic(50);
                if (!(value1 < var_d.length)) _desolexPanic(50);
                if (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1 <= 0x1) {
                    break;
                }
                if (!(0x0f & (value2 >> 0x04) < 0x10)) _desolexPanic(50);
                if (!((0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1) < var_d.length)) _desolexPanic(50);
                value1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1);
                value2 = (value2 >> 0x04) >> 0x04;
                value3 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1;
                value4 = value2 >> 0x04;
            }
            require(value4 == 0x0, "Strings: hex length insufficient");
            if (!(0x20 * 0x2 + 0x2 <= 0xffffffffffffffff)) _desolexPanic(65);
            var_d = var_d + (0x20 + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 & (0x1f + ((0x20 * 0x02) + 0x02))));
            uint256 value5 = (0x20 * 0x02) + 0x02;
            if ((0x20 * 0x02) + 0x02 != 0) {
                value5 = ((0x20 * 0x02) + 0x02) + (var_d + 0x20);
            }
            if (!(0 < var_d.length)) _desolexPanic(50);
            if (!(0x01 < var_d.length)) _desolexPanic(50);
            value1 = (0x20 * 0x02) + 0x01;
            value2 = stor_expr_h;
            uint256 value7;
            while (true) {
                uint256 value6 = value1;
                value7 = value2;
                if (value1 <= 0x1) {
                    break;
                }
                if (!((0xf & value2) < 0x10)) _desolexPanic(50);
                if (!(value1 < var_d.length)) _desolexPanic(50);
                if (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1 <= 0x1) {
                    break;
                }
                if (!(0x0f & (value2 >> 0x04) < 0x10)) _desolexPanic(50);
                if (!((0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1) < var_d.length)) _desolexPanic(50);
                value1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1);
                value2 = (value2 >> 0x04) >> 0x04;
                value6 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1;
                value7 = value2 >> 0x04;
            }
            require(value7 == 0x0, "Strings: hex length insufficient");
            uint256 value8 = 0;
            while (true) {
                uint256 value9 = value8;
                if (value8 >= var_p) {
                    break;
                }
                if (0x20 + value8 >= var_p) {
                    break;
                }
                value8 = 0x20 + (0x20 + value8);
                value9 = 0x20 + value8;
            }
            value8 = 0;
            while (true) {
                uint256 value10 = value8;
                if (value8 >= var_v) {
                    break;
                }
                if (0x20 + value8 >= var_v) {
                    break;
                }
                value8 = 0x20 + (0x20 + value8);
                value10 = 0x20 + value8;
            }
            var_d = 0x28 + (var_d.length + ((0x20 + var_d) + var_d.length));
            value8 = 0;
            while (true) {
                if (value8 >= var_d.length) {
                    break;
                }
                if (0x20 + value8 >= var_d.length) {
                    break;
                }
                value8 = 0x20 + (0x20 + value8);
                revert("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
            }
        }
        if (!(bytes1(hasRole[role][account]) != 0x0)) {
            hasRole[role][account] = true;
            emit RoleGranted(role, account, msg.sender);
        }
        uint256 value11 = 0;
        if (!(mapping_expr_m[account] != 0x0)) {
            getRoleMemberCount[role] = 0x01 + getRoleMemberCount[role];
            stor_expr_o = account;
            mapping_expr_m[account] = getRoleMemberCount[role];
            flag0 = true;
        }
    }
    
    function internal_86d(address account, bytes32 role) private {
        // Decompilation incomplete: helper effect provenance is conservative.
        if (!(bytes1(hasRole[stor_expr_ag][msg.sender]) != 0x0)) {
            if (!(0x14 * 0x2 + 0x2 <= 0xffffffffffffffff)) _desolexPanic(65);
            uint256 var_d;
            var_d = var_d + (0x20 + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 & (0x1f + ((0x14 * 0x02) + 0x02))));
            uint256 value0 = (0x14 * 0x02) + 0x02;
            if (0x14 * 0x2 + 0x2 != 0x0) {
                value0 = ((0x14 * 0x02) + 0x02) + (var_d + 0x20);
            }
            if (!(0 < var_d.length)) _desolexPanic(50);
            if (!(0x01 < var_d.length)) _desolexPanic(50);
            uint256 value1 = (0x14 * 0x02) + 0x01;
            uint256 value2 = msg.sender;
            uint256 value4;
            while (true) {
                uint256 value3 = value1;
                value4 = value2;
                if (value1 <= 0x1) {
                    break;
                }
                if (!((0xf & value2) < 0x10)) _desolexPanic(50);
                if (!(value1 < var_d.length)) _desolexPanic(50);
                if (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1 <= 0x1) {
                    break;
                }
                if (!(0x0f & (value2 >> 0x04) < 0x10)) _desolexPanic(50);
                if (!((0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1) < var_d.length)) _desolexPanic(50);
                value1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1);
                value2 = (value2 >> 0x04) >> 0x04;
                value3 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1;
                value4 = value2 >> 0x04;
            }
            require(value4 == 0x0, "Strings: hex length insufficient");
            if (!(0x20 * 0x2 + 0x2 <= 0xffffffffffffffff)) _desolexPanic(65);
            var_d = var_d + (0x20 + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 & (0x1f + ((0x20 * 0x02) + 0x02))));
            uint256 value5 = (0x20 * 0x02) + 0x02;
            if ((0x20 * 0x02) + 0x02 != 0) {
                value5 = ((0x20 * 0x02) + 0x02) + (var_d + 0x20);
            }
            if (!(0 < var_d.length)) _desolexPanic(50);
            if (!(0x01 < var_d.length)) _desolexPanic(50);
            value1 = (0x20 * 0x02) + 0x01;
            value2 = stor_expr_ag;
            uint256 value7;
            while (true) {
                uint256 value6 = value1;
                value7 = value2;
                if (value1 <= 0x1) {
                    break;
                }
                if (!((0xf & value2) < 0x10)) _desolexPanic(50);
                if (!(value1 < var_d.length)) _desolexPanic(50);
                if (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1 <= 0x1) {
                    break;
                }
                if (!(0x0f & (value2 >> 0x04) < 0x10)) _desolexPanic(50);
                if (!((0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1) < var_d.length)) _desolexPanic(50);
                value1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1);
                value2 = (value2 >> 0x04) >> 0x04;
                value6 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + value1;
                value7 = value2 >> 0x04;
            }
            require(value7 == 0x0, "Strings: hex length insufficient");
            uint256 value8 = 0;
            while (true) {
                uint256 value9 = value8;
                if (value8 >= var_p) {
                    break;
                }
                if (0x20 + value8 >= var_p) {
                    break;
                }
                value8 = 0x20 + (0x20 + value8);
                value9 = 0x20 + value8;
            }
            value8 = 0;
            while (true) {
                uint256 value10 = value8;
                if (value8 >= var_v) {
                    break;
                }
                if (0x20 + value8 >= var_v) {
                    break;
                }
                value8 = 0x20 + (0x20 + value8);
                value10 = 0x20 + value8;
            }
            var_d = 0x28 + (var_d.length + ((0x20 + var_d) + var_d.length));
            value8 = 0;
            while (true) {
                if (value8 >= var_d.length) {
                    break;
                }
                if (0x20 + value8 >= var_d.length) {
                    break;
                }
                value8 = 0x20 + (0x20 + value8);
                revert("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
            }
        }
        if (bytes1(hasRole[role][account])) {
            hasRole[role][account] = false;
            emit RoleRevoked(role, account, msg.sender);
        }
        uint256 value11 = 0;
        if (mapping_expr_ah[account] != 0) {
            if (!((getRoleMemberCount[role] - 0x01) == ((mapping_expr_ah[account] - 0x01)))) {
                if (!((getRoleMemberCount[role] - 0x01) < stor_expr_ak)) _desolexPanic(50);
                if (!((mapping_expr_ah[account] - 0x01) < stor_expr_ak)) _desolexPanic(50);
                stor_expr_al = stor_expr_am;
                mapping_expr_ah[stor_expr_am] = mapping_expr_ah[account];
            }
            if (!(getRoleMemberCount[role] != 0x0)) _desolexPanic(49);
            stor_expr_ao = 0;
            getRoleMemberCount[role] = getRoleMemberCount[role] - 0x01;
            mapping_expr_ap[account] = 0;
            flag0 = true;
        }
    }
    
    function __desolexSelectorShim(uint32 rewrittenSelector) private {
        assembly {
            let input := mload(0x40)
            calldatacopy(input, 0, calldatasize())
            mstore(input, or(and(mload(input), 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff), shl(224, and(rewrittenSelector, 0xffffffff))))
            let success := delegatecall(gas(), address(), input, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(input, 0, size)
            switch success
            case 0 { revert(input, size) }
            default { return(input, size) }
        }
    }
    
    // Note: This selector table is synthetic and is not part of the original Solidity source.
    // It records the recovered selector-to-signature mapping without executable behavior.
    
    // 0x01ffc9a7 => supportsInterface(bytes4)
    // 0x0682bdbc => signAddress()
    // 0x087bc228 => setConfig(address,address,address,address)
    // 0x1581b600 => withdrawAddress()
    // 0x248a9ca3 => getRoleAdmin(bytes32)
    // 0x2f2ff15d => grantRole(bytes32,address)
    // 0x34a1bedb => admin(address,address,uint256)
    // 0x3644e515 => DOMAIN_SEPARATOR()
    // 0x36568abe => renounceRole(bytes32,address)
    // 0x4a28d784 => Unknown_4a28d784(uint256,uint256,uint256,bool,uint256,uint256,bytes32,bool,uint256,uint256)
    // 0x4de10d6f => BTCX()
    // 0x8747bf9c => withdrawInfo(uint256)
    // 0x9010d07c => Unknown_9010d07c(uint256,uint256)
    // 0x91d14854 => hasRole(bytes32,address)
    // 0xa217fddf => DEFAULT_ADMIN_ROLE()
    // 0xca15c873 => getRoleMemberCount(bytes32)
    // 0xd547741f => revokeRole(bytes32,address)
    // 0xe82bef29 => fundAddress()
}
0xda43dd…135568 on BNB Chain — Decompiled Solidity