Sepolia Testnet

Contract

0x2C123047B23809DbCCDA2d34bB5158D2563221E3

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Upgrade68976752024-10-18 10:11:1293 days ago1729246272IN
0x2C123047...2563221E3
0 ETH0.003318721.04172083
Upgrade68974032024-10-18 9:09:0093 days ago1729242540IN
0x2C123047...2563221E3
0 ETH0.0014699822.89230212
Upgrade68731702024-10-14 8:07:2497 days ago1728893244IN
0x2C123047...2563221E3
0 ETH0.03525216107.85427446
Upgrade68730702024-10-14 7:42:1297 days ago1728891732IN
0x2C123047...2563221E3
0 ETH0.0084841691.75939729
Spend Rewards On...67932092024-10-01 8:57:36110 days ago1727773056IN
0x2C123047...2563221E3
0 ETH0.10773616331.0426039
Spend Rewards On...65504472024-08-22 16:02:00150 days ago1724342520IN
0x2C123047...2563221E3
0 ETH0.0110435133.92983416
Create A New Rew...65439882024-08-21 15:43:12151 days ago1724254992IN
0x2C123047...2563221E3
0 ETH0.0375872616.86063026
Create A New Rew...65436002024-08-21 14:13:24151 days ago1724249604IN
0x2C123047...2563221E3
0 ETH0.0336445215.09218509
0xd11137c558229032024-05-02 17:30:12262 days ago1714671012IN
0x2C123047...2563221E3
0 ETH0.0020266546.20206587
0xd11137c557771342024-04-25 21:36:00268 days ago1714080960IN
0x2C123047...2563221E3
0 ETH0.000182943.00028749
Get Protocol Rec...57771112024-04-25 21:31:24268 days ago1714080684IN
0x2C123047...2563221E3
0 ETH0.000134743.00023231
Set Forwarder Ad...57668662024-04-24 11:11:00270 days ago1713957060IN
0x2C123047...2563221E3
0 ETH0.000067151.20011989
Upgrade56496032024-04-07 19:53:36286 days ago1712519616IN
0x2C123047...2563221E3
0 ETH0.000496271.00054888
Upgrade56493292024-04-07 18:52:48287 days ago1712515968IN
0x2C123047...2563221E3
0 ETH0.000173991.5005216
Upgrade54698892024-03-12 10:26:12313 days ago1710239172IN
0x2C123047...2563221E3
0 ETH0.01732195109.82726791
Grant Role To Ac...54450512024-03-08 22:56:12316 days ago1709938572IN
0x2C123047...2563221E3
0 ETH0.00882648146.85360903
Update Protocol ...54450502024-03-08 22:56:00316 days ago1709938560IN
0x2C123047...2563221E3
0 ETH0.01016189157.84485977
Initialize Proto...54450492024-03-08 22:55:48316 days ago1709938548IN
0x2C123047...2563221E3
0 ETH0.03325921146.1660918
Upgrade54450482024-03-08 22:55:36316 days ago1709938536IN
0x2C123047...2563221E3
0 ETH0.41105143153.5538165

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
74671952025-01-11 9:20:248 days ago1736587224
0x2C123047...2563221E3
 Contract Creation0 ETH
74671952025-01-11 9:20:248 days ago1736587224
0x2C123047...2563221E3
 Contract Creation0 ETH
74472122025-01-08 14:33:2411 days ago1736346804
0x2C123047...2563221E3
 Contract Creation0 ETH
74472122025-01-08 14:33:2411 days ago1736346804
0x2C123047...2563221E3
 Contract Creation0 ETH
74460522025-01-08 10:31:2411 days ago1736332284
0x2C123047...2563221E3
 Contract Creation0 ETH
74460522025-01-08 10:31:2411 days ago1736332284
0x2C123047...2563221E3
 Contract Creation0 ETH
74455192025-01-08 8:39:0011 days ago1736325540
0x2C123047...2563221E3
 Contract Creation0 ETH
74455192025-01-08 8:39:0011 days ago1736325540
0x2C123047...2563221E3
 Contract Creation0 ETH
73397752024-12-23 17:38:2427 days ago1734975504
0x2C123047...2563221E3
 Contract Creation0 ETH
73397752024-12-23 17:38:2427 days ago1734975504
0x2C123047...2563221E3
 Contract Creation0 ETH
73376482024-12-23 10:08:1227 days ago1734948492
0x2C123047...2563221E3
 Contract Creation0 ETH
73376482024-12-23 10:08:1227 days ago1734948492
0x2C123047...2563221E3
 Contract Creation0 ETH
73134352024-12-19 20:28:1230 days ago1734640092
0x2C123047...2563221E3
 Contract Creation0 ETH
73134352024-12-19 20:28:1230 days ago1734640092
0x2C123047...2563221E3
 Contract Creation0 ETH
73052402024-12-18 15:23:4832 days ago1734535428
0x2C123047...2563221E3
 Contract Creation0 ETH
73052402024-12-18 15:23:4832 days ago1734535428
0x2C123047...2563221E3
 Contract Creation0 ETH
72427892024-12-09 9:54:3641 days ago1733738076
0x2C123047...2563221E3
 Contract Creation0 ETH
72427892024-12-09 9:54:3641 days ago1733738076
0x2C123047...2563221E3
 Contract Creation0 ETH
72426172024-12-09 9:17:4841 days ago1733735868
0x2C123047...2563221E3
 Contract Creation0 ETH
72426172024-12-09 9:17:4841 days ago1733735868
0x2C123047...2563221E3
 Contract Creation0 ETH
72400672024-12-09 0:18:3641 days ago1733703516
0x2C123047...2563221E3
 Contract Creation0 ETH
72400672024-12-09 0:18:3641 days ago1733703516
0x2C123047...2563221E3
 Contract Creation0 ETH
72399642024-12-08 23:56:4841 days ago1733702208
0x2C123047...2563221E3
 Contract Creation0 ETH
72399642024-12-08 23:56:4841 days ago1733702208
0x2C123047...2563221E3
 Contract Creation0 ETH
72397682024-12-08 23:16:0041 days ago1733699760
0x2C123047...2563221E3
 Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Main

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 12 : main.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {MainProvider as provider} from "./providers/main.provider.sol";
import {ProtocolData as protocolProvider} from "../providers/data/protocol.sol";
import {Params} from "../providers/common/params.sol";
import {UpgradeController as upgrader} from "./controllers/upgrade.controller.sol";
import {Data as Dto} from "../providers/data/main.sol";
import {Database as Positions} from "../providers/common/database.sol";
import {Errors} from "../providers/common/errors.sol";

contract Main {
    constructor(address _admin, address _upgrader, Params.EditableProtocolRecords memory newRecord) payable {
        provider.setMainAdmin(_admin);
        protocolProvider.updateProtocolRecords(newRecord);
        Dto.UpgradeDetails[] memory upgrade = new Dto.UpgradeDetails[](1);
        bytes4[] memory functionSelectors = new bytes4[](1);
        functionSelectors[0] = upgrader.upgrade.selector;
        upgrade[0] = Dto.UpgradeDetails({
            moduleAddress: _upgrader,
            action: Dto.UpgradeAction.Add,
            functionSelectors: functionSelectors
        });
        provider.upgrade(upgrade, address(0), "");
    }

    fallback() external payable {
        provider.MainStorage storage ms;
        bytes32 position = Positions.MAIN_STORAGE_POSITION;
        assembly {
            ms.slot := position
        }
        address module = ms.selectorToModuleAndPosition[msg.sig].moduleAddress;
        require(module != address(0), Errors.MODULE_DOES_NOT_EXIST);
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), module, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

File 2 of 12 : main.provider.sol
// SPDX-License-Identifier: MIT
//@dev to optimize for gas

pragma solidity ^0.8.20;

import {UpgradeController as Upgrader} from "../controllers/upgrade.controller.sol";
import {Data as Dto} from "../../providers/data/main.sol";
import {Database as Positions} from "../../providers/common/database.sol";
import {Errors} from "../../providers/common/errors.sol";

error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);

library MainProvider {
    struct ModuleAddressAndPosition {
        address moduleAddress;
        uint96 functionSelectorPosition;
    }

    struct ModuleFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 moduleAddressPosition;
    }

    struct MainStorage {
        mapping(bytes4 => ModuleAddressAndPosition) selectorToModuleAndPosition;
        mapping(address => ModuleFunctionSelectors) moduleFunctionSelectors;
        address[] moduleAddresses;
        mapping(bytes4 => bool) supportedInterfaces;
        address admin;
    }

    function mainStorage() internal pure returns (MainStorage storage ms) {
        bytes32 position = Positions.MAIN_STORAGE_POSITION;
        assembly {
            ms.slot := position
        }
    }

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function setMainAdmin(address _newOwner) internal {
        MainStorage storage ms = mainStorage();
        address previousOwner = ms.admin;
        ms.admin = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }

    function getMainAdmin() internal view returns (address admin_) {
        admin_ = mainStorage().admin;
    }

    function enforceIsAdmin() internal view {
        require(msg.sender == mainStorage().admin, Errors.CALLER_IS_NOT_CONTRACT_OWNER);
    }

    event Upgraded(Dto.UpgradeDetails[] _upgradeDetails, address _init, bytes _calldata);

    function upgrade(Dto.UpgradeDetails[] memory _upgradeDetails, address _init, bytes memory _calldata) internal {
        for (uint256 moduleIndex; moduleIndex < _upgradeDetails.length; moduleIndex++) {
            Dto.UpgradeAction action = _upgradeDetails[moduleIndex].action;
            if (action == Dto.UpgradeAction.Add) {
                addServices(_upgradeDetails[moduleIndex].moduleAddress, _upgradeDetails[moduleIndex].functionSelectors);
            } else if (action == Dto.UpgradeAction.Replace) {
                replaceServices(
                    _upgradeDetails[moduleIndex].moduleAddress, _upgradeDetails[moduleIndex].functionSelectors
                );
            } else if (action == Dto.UpgradeAction.Remove) {
                removeServices(
                    _upgradeDetails[moduleIndex].moduleAddress, _upgradeDetails[moduleIndex].functionSelectors
                );
            } else {
                revert(Errors.INCORRECT_UPGRADE_ACTION);
            }
        }
        emit Upgraded(_upgradeDetails, _init, _calldata);
        initializeUpgrader(_init, _calldata);
    }

    function addServices(address _moduleAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, Errors.NO_SELECTOR_IN_SPECIFIED_MODULE);

        MainStorage storage ms = mainStorage();
        require(_moduleAddress != address(0), Errors.ZERO_ADDRESS_NOT_ALLOWED);
        uint96 selectorPosition = uint96(ms.moduleFunctionSelectors[_moduleAddress].functionSelectors.length);

        if (selectorPosition == 0) {
            addModule(ms, _moduleAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldModuleAddress = ms.selectorToModuleAndPosition[selector].moduleAddress;
            require(oldModuleAddress == address(0), Errors.MODULE_ALREADY_EXISTS);
            addService(ms, selector, selectorPosition, _moduleAddress);
            selectorPosition++;
        }
    }

    function replaceServices(address _moduleAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, Errors.NO_SELECTOR_IN_SPECIFIED_MODULE);
        MainStorage storage ms = mainStorage();
        require(_moduleAddress != address(0), Errors.ZERO_ADDRESS_NOT_ALLOWED);
        uint96 selectorPosition = uint96(ms.moduleFunctionSelectors[_moduleAddress].functionSelectors.length);

        if (selectorPosition == 0) {
            addModule(ms, _moduleAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldModuleAddress = ms.selectorToModuleAndPosition[selector].moduleAddress;
            require(oldModuleAddress != _moduleAddress, Errors.MODULE_IS_SAME_AS_THAT_TO_BE_REPLACED);
            removeService(ms, oldModuleAddress, selector);
            addService(ms, selector, selectorPosition, _moduleAddress);
            selectorPosition++;
        }
    }

    function removeServices(address _moduleAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, Errors.NO_SELECTOR_IN_SPECIFIED_MODULE);
        MainStorage storage ms = mainStorage();

        require(_moduleAddress == address(0), Errors.REMOVE_MODULE_ADDRESS_MUST_BE_ZERO_ADDRESS);
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldModuleAddress = ms.selectorToModuleAndPosition[selector].moduleAddress;
            removeService(ms, oldModuleAddress, selector);
        }
    }

    function addModule(MainStorage storage ms, address _moduleAddress) internal {
        enforceHasContractCode(_moduleAddress, "LibDiamondCut: New facet has no code");
        ms.moduleFunctionSelectors[_moduleAddress].moduleAddressPosition = ms.moduleAddresses.length;
        ms.moduleAddresses.push(_moduleAddress);
    }

    function addService(MainStorage storage ms, bytes4 _selector, uint96 _selectorPosition, address _moduleAddress)
        internal
    {
        ms.selectorToModuleAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ms.moduleFunctionSelectors[_moduleAddress].functionSelectors.push(_selector);
        ms.selectorToModuleAndPosition[_selector].moduleAddress = _moduleAddress;
    }

    function removeService(MainStorage storage ms, address _moduleAddress, bytes4 _selector) internal {
        require(_moduleAddress != address(0), Errors.SERVICE_OR_PROVIDER_DOES_NOT_EXIST);
        require(_moduleAddress != address(this), Errors.CAN_NOT_REMOVE_THIS_SERVICE_OR_PROVIDER);
        uint256 selectorPosition = ms.selectorToModuleAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ms.moduleFunctionSelectors[_moduleAddress].functionSelectors.length - 1;
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ms.moduleFunctionSelectors[_moduleAddress].functionSelectors[lastSelectorPosition];
            ms.moduleFunctionSelectors[_moduleAddress].functionSelectors[selectorPosition] = lastSelector;
            ms.selectorToModuleAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }
        ms.moduleFunctionSelectors[_moduleAddress].functionSelectors.pop();
        delete ms.selectorToModuleAndPosition[_selector];

        if (lastSelectorPosition == 0) {
            uint256 lastModuleAddressPosition = ms.moduleAddresses.length - 1;
            uint256 moduleAddressPosition = ms.moduleFunctionSelectors[_moduleAddress].moduleAddressPosition;
            if (moduleAddressPosition != lastModuleAddressPosition) {
                address lastModuleAddress = ms.moduleAddresses[lastModuleAddressPosition];
                ms.moduleAddresses[moduleAddressPosition] = lastModuleAddress;
                ms.moduleFunctionSelectors[lastModuleAddress].moduleAddressPosition = moduleAddressPosition;
            }
            ms.moduleAddresses.pop();
            delete ms.moduleFunctionSelectors[_moduleAddress].moduleAddressPosition;
        }
    }

    function initializeUpgrader(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            return;
        }
        enforceHasContractCode(_init, Errors.INIT_ADDRESS_HAS_NO_CODE);
        (bool success, bytes memory error) = _init.delegatecall(_calldata);
        if (!success) {
            if (error.length > 0) {
                assembly {
                    let returndata_size := mload(error)
                    revert(add(32, error), returndata_size)
                }
            } else {
                revert InitializationFunctionReverted(_init, _calldata);
            }
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}

File 3 of 12 : protocol.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Database, Params, Validator, Errors} from "../common/database.sol";

library ProtocolData {
    struct ProtocolConfig {
        uint256 defaultMinimumMeForConversation;
        uint256 defaultMinimumRewardForConversationInPercent;
        uint256 defaultMaximumRLimitForConversationInPrecision;
        uint256 defaultRewardNotifyThresholdInPercent;
        uint256 defaultNotifyMeAmount;
        uint256 defaultNotifyRewardAmountInPercent;
        uint256 caiInMe;
        uint256 protocolFee;
        uint256 bountyContributionInPrecision;
        uint256 conversationSlippageInPrecision;
        uint256 informationSlippageInPrecision;
    }

    struct ProtocolRecords {
        address meId;
        address bountyId;
        address treasuryId;
        address vaultId;
        bytes10 adminId;
        uint256 totalNumberOfBrands;
        uint256 totalNumberOfRewards;
        uint256 lastUpdated;
        bool initialized;
    }

    function writableProtocolRecords() internal pure returns (ProtocolRecords storage records) {
        bytes32 position = Database.PROTOCOL_RECORDS;
        assembly {
            records.slot := position
        }
    }

    function writableProtocolConfigs() internal pure returns (ProtocolConfig storage config) {
        bytes32 position = Database.PROTOCOL_CONFIGS;
        assembly {
            config.slot := position
        }
    }

    function init() internal {
        ProtocolRecords storage records = writableProtocolRecords();
        if (records.initialized) {
            revert Errors.ALREADY_INITIALIZED();
        }
        records.initialized = true;
    }

    function getMeId() internal view returns (address meId) {
        ProtocolRecords storage records = writableProtocolRecords();
        meId = records.meId;
    }

    function updateMeId(address newMeId, uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.meId = newMeId;
        records.lastUpdated = lastUpdatedAt;

        return true;
    }

    function getBountyId() internal view returns (address bountyId) {
        ProtocolRecords storage records = writableProtocolRecords();
        bountyId = records.bountyId;
    }

    function getVaultId() internal view returns (address vaultId) {
        ProtocolRecords storage records = writableProtocolRecords();
        vaultId = records.vaultId;
    }

    function updateBountyId(address newBountyId, uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.bountyId = newBountyId;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function updateVaultId(address newVaultId, uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.vaultId = newVaultId;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function getTreasuryId() internal view returns (address treasuryId) {
        ProtocolRecords storage records = writableProtocolRecords();
        treasuryId = records.treasuryId;
    }

    function updateTreasuryId(address newTreasuryId, uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.treasuryId = newTreasuryId;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function getAdminId() internal view returns (bytes10 adminId) {
        ProtocolRecords storage records = writableProtocolRecords();
        adminId = records.adminId;
    }

    function updateAdminId(bytes10 newAdminId, uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.adminId = newAdminId;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function getConversationSlippageInPrecision() internal view returns (uint256 defaultSlippage) {
        ProtocolConfig storage config = writableProtocolConfigs();
        return config.conversationSlippageInPrecision;
    }

    function getCai() internal view returns (uint256) {
        ProtocolConfig storage config = writableProtocolConfigs();
        return config.caiInMe;
    }

    function getTotalNumberOfBrands() internal view returns (uint256 totalNumberOfBrands) {
        ProtocolRecords storage records = writableProtocolRecords();
        totalNumberOfBrands = records.totalNumberOfBrands;
    }

    function updateTotalNumberOfBrands(uint256 newTotalNumberOfBrands, uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.totalNumberOfBrands = newTotalNumberOfBrands;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function incrementTotalNumberOfBrands(uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        uint256 currentTotalNumberOfBrands = records.totalNumberOfBrands;
        records.totalNumberOfBrands = currentTotalNumberOfBrands + 1;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function getTotalNumberOfRewards() internal view returns (uint256 totalNumberOfRewards) {
        ProtocolRecords storage records = writableProtocolRecords();
        totalNumberOfRewards = records.totalNumberOfRewards;
    }

    function updateTotalNumberOfRewards(uint256 newTotalNumberOfRewards, uint256 lastUpdatedAt)
        internal
        returns (bool)
    {
        ProtocolRecords storage records = writableProtocolRecords();
        records.totalNumberOfRewards = newTotalNumberOfRewards;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function incrementTotalNumberOfRewards(uint256 lastUpdatedAt) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        uint256 currentTotalNumberOfRewards = records.totalNumberOfRewards;
        records.totalNumberOfRewards = currentTotalNumberOfRewards + 1;
        records.lastUpdated = lastUpdatedAt;
        return true;
    }

    function getLastUpdated() internal view returns (uint256 lastUpdated) {
        ProtocolRecords storage records = writableProtocolRecords();
        lastUpdated = records.lastUpdated;
    }

    function getProtocolRecords() internal view returns (ProtocolRecords memory _records) {
        ProtocolRecords storage records = writableProtocolRecords();
        _records = records;
    }

    function getProtocolConfig() internal view returns (ProtocolConfig memory _config) {
        ProtocolConfig storage configs = writableProtocolConfigs();
        _config = configs;
    }

    function updateProtocolConfig(Params.EditableProtocolConfig memory newConfig) internal returns (bool) {
        ProtocolConfig storage config = writableProtocolConfigs();
        config.defaultMinimumRewardForConversationInPercent = newConfig.defaultMinimumRewardForConversationInPercent;
        config.defaultMinimumMeForConversation = newConfig.defaultMinimumMeForConversation;
        config.defaultMaximumRLimitForConversationInPrecision = newConfig.defaultMaximumRLimitForConversationInPrecision;
        config.defaultRewardNotifyThresholdInPercent = newConfig.defaultRewardNotifyThresholdInPercent;
        config.defaultNotifyMeAmount = newConfig.defaultNotifyMeAmount;
        config.defaultNotifyRewardAmountInPercent = newConfig.defaultNotifyRewardAmountInPercent;
        config.caiInMe = newConfig.caiInMe;
        config.protocolFee = newConfig.protocolFee;
        config.bountyContributionInPrecision = newConfig.bountyContributionInPrecision;
        config.conversationSlippageInPrecision = newConfig.conversationSlippageInPrecision;
        config.informationSlippageInPrecision = newConfig.informationSlippageInPrecision;
        return true;
    }

    function initProtocol(Params.EditableProtocolConfig memory newConfig) internal returns (bool) {
        updateProtocolConfig(newConfig);

        return true;
    }

    function updateProtocolRecords(Params.EditableProtocolRecords memory newRecord) internal returns (bool) {
        ProtocolRecords storage records = writableProtocolRecords();
        records.meId = newRecord.meId;
        records.bountyId = newRecord.bountyId;
        records.treasuryId = newRecord.treasuryId;
        records.adminId = newRecord.adminId;
        records.vaultId = newRecord.vaultId;

        return true;
    }

    function updateProtocolConfigIgnoreDefault(Params.EditableProtocolConfig memory newConfig)
        internal
        returns (bool)
    {
        ProtocolConfig storage config = writableProtocolConfigs();

        if (!Validator.isZero(newConfig.defaultMinimumRewardForConversationInPercent)) {
            config.defaultMinimumRewardForConversationInPercent = newConfig.defaultMinimumRewardForConversationInPercent;
        }
        if (!Validator.isZero(newConfig.defaultMinimumMeForConversation)) {
            config.defaultMinimumMeForConversation = newConfig.defaultMinimumMeForConversation;
        }
        if (!Validator.isZero(newConfig.defaultMaximumRLimitForConversationInPrecision)) {
            config.defaultMaximumRLimitForConversationInPrecision =
                newConfig.defaultMaximumRLimitForConversationInPrecision;
        }
        if (!Validator.isZero(newConfig.defaultRewardNotifyThresholdInPercent)) {
            config.defaultRewardNotifyThresholdInPercent = newConfig.defaultRewardNotifyThresholdInPercent;
        }
        if (!Validator.isZero(newConfig.defaultNotifyMeAmount)) {
            config.defaultNotifyMeAmount = newConfig.defaultNotifyMeAmount;
        }
        if (!Validator.isZero(newConfig.defaultNotifyRewardAmountInPercent)) {
            config.defaultNotifyRewardAmountInPercent = newConfig.defaultNotifyRewardAmountInPercent;
        }
        if (!Validator.isZero(newConfig.caiInMe)) {
            config.caiInMe = newConfig.caiInMe;
        }
        if (!Validator.isZero(newConfig.protocolFee)) {
            config.protocolFee = newConfig.protocolFee;
        }
        if (!Validator.isZero(newConfig.bountyContributionInPrecision)) {
            config.bountyContributionInPrecision = newConfig.bountyContributionInPrecision;
        }
        if (!Validator.isZero(newConfig.conversationSlippageInPrecision)) {
            config.conversationSlippageInPrecision = newConfig.conversationSlippageInPrecision;
        }
        if (!Validator.isZero(newConfig.informationSlippageInPrecision)) {
            config.informationSlippageInPrecision = newConfig.informationSlippageInPrecision;
        }
        return true;
    }
}

File 4 of 12 : params.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library Params {
    ///Brands
    struct EditableBrandDetails {
        string name;
        string onlinePresence;
    }

    struct EditableBrandConfig {
        bool enableBountyRewards;
        bool enableCais;
        bool payIncomingGasFees;
        bool payOutgoingGasFees;
    }

    ///Rewards
    struct EditableRewardDetails {
        string name;
        string symbol;
        string descriptionLink;
    }

    struct EditableRewardConfig {
        bool specificException;
        bool bountyEnables;
        bool caiEnabled;
        uint256 bountyTriggerLimit;
        uint256 bountyContributionInPrecision;
        bool payIncomingGasFee;
        bool payOutgoingGasFee;
    }

    //Protocol
    struct EditableProtocolConfig {
        uint256 defaultMinimumMeForConversation;
        uint256 defaultMinimumRewardForConversationInPercent;
        uint256 defaultMaximumRLimitForConversationInPrecision;
        uint256 defaultRewardNotifyThresholdInPercent;
        uint256 defaultNotifyMeAmount;
        uint256 defaultNotifyRewardAmountInPercent;
        uint256 caiInMe;
        uint256 protocolFee;
        uint256 bountyContributionInPrecision;
        uint256 conversationSlippageInPrecision;
        uint256 informationSlippageInPrecision;
    }

    struct EditableProtocolRecords {
        address meId;
        address bountyId;
        address treasuryId;
        address vaultId;
        bytes10 adminId;
    }

    ///Treasury
    struct EditableTreasuryRecords {
        address meId;
        uint256 meNofityLimit;
    }

    ///Pool
    struct ConfigForTypeAOpenRewards {
        uint256 rOptimal;
        uint256 maximumRLimit;
        uint256 minimumRewardAmountForConversation;
        uint256 minimumMeAmountForConversation;
        uint256 notifyRewardAmount;
        uint256 notifyMeAmount;
        uint256 defaultSlippageInPrecision;
        bool allowSwaps;
    }

    struct EditableConfigForTypeAOpenRewards {
        uint256 maximumRLimit;
        uint256 minimumRewardAmountForConversation;
        uint256 minimumMeAmountForConversation;
        uint256 notifyRewardAmount;
        uint256 notifyMeAmount;
        uint256 defaultSlippageInPrecision;
        bool allowSwaps;
    }

    struct CurrentStateOfTypeAOpenRewards {
        bool started;
        bool active;
        address initiator;
        address reward;
        address meToken;
        uint256 lastRewardAmount;
        uint256 lastMeAmount;
        uint256 meTokensFromProtocolTeam;
        uint256 setupMeAmount;
        uint40 lastTransactionTime;
    }

    struct LiquidityInfo {
        uint256 position;
        uint256 rewardAmount;
        uint256 meAmount;
        address requestor;
        address to;
    }

    struct ExtendedLiquidityInfo {
        uint256 rewardAmount;
        uint256 meAmount;
        uint256 currentRewardAmount;
        uint256 currentMeAmount;
        uint256 minimumRewardAmountForConversation;
        uint256 minimumMeAmountForConversation;
        uint256 meTokensFromProtocolTeam;
        uint256 rOptimal;
    }

    struct OutgoingConversationInfo {
        uint256 rewardAmountIn;
        uint256 expectedAmountOfOutputReward;
        address listener;
        uint256 listenerROptimal;
        address requestor;
        address outputRewardReceiver;
    }

    struct spendingInfo {
        address rewardAtHand;
        address targettedReward;
        uint256 amountOfRewardAtHand;
        uint256 expectedAmountOfTargetedReward;
    }

    struct PermitParam {
        uint256 _deadline;
        uint8 _v;
        bytes32 _r;
        bytes32 _s;
    }

    struct VaultPermitParams {
        address owner;
        address spender;
        address reward;
        uint256 value;
        uint256 count;
        bytes32 prefixedHash;
        bytes32 globalHash;
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    struct InitialSupplyParams {
        address vaultAddress;
        address treasuryAddress;
        uint256 initialSupplyVaultAmount;
        uint256 initialSupplyTreasuryAmount;
    }

    struct InitialSupplyGenericParams {
        uint256 amountOne;
        uint256 amountTwo;
        address recipientOne;
        address recipientTwo;
    }

    struct TreasuryPermitParams {
        address owner; // brand
        address spender; // reward
        uint256 value;
        uint256 deadline;
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    struct RoleParams {
        bytes32 role;
        address account;
    }

    struct InitiateConversationReturnType {
        uint256 currentAmountOfMeTokensrewardOne;
        uint256 currentAmountOfRewardTokensrewardOne;
        uint256 notifyRewardAmountrewardOne;
        uint256 notifyMeTokenAmountrewardOne;
        uint256 currentAmountOfMeTokensRewardTwo;
        uint256 currentAmountOfRewardTokensRewardTwo;
        uint256 notifyRewardAmountRewardTwo;
        uint256 notifyMeTokenAmountRewardTwo;
        uint256 outputRewardsAmount;
        uint256 currentDepositNonceRewardOne;
        uint256 currentDepositNonceRewardTwo;
    }
}

File 5 of 12 : upgrade.controller.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Data as Dto} from "../../providers/data/main.sol";

interface UpgradeController {
    function upgrade(Dto.UpgradeDetails[] calldata _upgradeDetails, address _init, bytes calldata _calldata) external;

    event Upgraded(Dto.UpgradeDetails[] _upgradeDetails, address _init, bytes _calldata);
}

File 6 of 12 : main.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library Data {
    enum UpgradeAction {
        Add,
        Replace,
        Remove
    }

    struct UpgradeDetails {
        address moduleAddress;
        UpgradeAction action;
        bytes4[] functionSelectors;
    }

    struct Module {
        address ModuleAddress;
        bytes4[] functionSelectors;
    }

    struct PoolTokens {
        uint256 numerator;
        uint256 divisor;
    }
}

File 7 of 12 : database.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Errors} from "./errors.sol";
import {Validator} from "./validators.sol";
import {Params} from "./params.sol";
import {Constants} from "./constants.sol";
import {RoleGuard, Roles} from "./roleguard.sol";

library Database {
    bytes32 constant MAIN_STORAGE_POSITION = keccak256("me.protocol.pool.main.storage");
    bytes32 constant BRAND_RECORDS = keccak256("me.protocol.brand.records");
    bytes32 constant REWARD_RECORDS = keccak256("me.protocol.rewards.records");
    bytes32 constant BOUNTY_RECORDS = keccak256("me.protocol.bounty.records");
    bytes32 constant PROTOCOL_RECORDS = keccak256("me.protocol.protocol.records");
    bytes32 constant PROTOCOL_CONFIGS = keccak256("me.protocol.protocol.configs");
    bytes32 constant CONTEXT_RECORD = keccak256("me.protocol.protocol.context");

    bytes32 constant TREASURY_RECORDS = keccak256("me.protocol.treasury.records");
    bytes32 constant ACCESS_RECORDS = keccak256("me.protocol.access.records");
    bytes32 constant VAULT_RECORDS = keccak256("me.protocol.vault.records");
    bytes32 constant OPEN_REWARDS_STATE_TYPE_A = keccak256("me.protocol.openrewards.state.type.a");
    bytes32 constant OPEN_REWARDS_CONFIG_TYPE_A = keccak256("me.protocol.openrewards.config.type.a");
    bytes32 constant OPEN_REWARDS_POSITIONS_TYPE_A = keccak256("me.protocol.openrewards.positions.type.a");
    bytes32 constant RUNTIME_STORAGE_POSITION = keccak256("me.protocol.pool.runtime.storage");
}

File 8 of 12 : errors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library Errors {
    error ADDRESS_ZERO_NOT_ALLOWED();
    error ZERO_NOT_ALLOWED();
    error EMPTY_STRING_NOT_ALLOWED();
    error EMPTY_REASON_NOT_ALLOWED();
    error OPEN_REWARDS_NOT_STARTED();
    error OPEN_REWARDS_ALREADY_STARTED();
    error OPEN_REWARDS_IS_PAUSED();
    error OPEN_REWARDS_IS_ACTIVE();
    error OPEN_REWARDS_IS_NOT_ACTIVE();
    error OPTIMAL_REWARD_RATIO_CANNOT_BE_ZERO();
    error MAXIMUM_REWARD_RATIO_CANNOT_BE_LESS_THAN_THE_OPTIMAL_RATIO();
    error OPEN_REWARDS_SHOULD_START_AT_R_OPTIMAL_OR_LESS();
    error EXPECTED_PROTOCOL_ME_OFFSET_EXCEEDS_ACTUAL_ME_OFFSET();
    error CONVERSATION_WILL_CAUSE_POOL_TO_GO_OUT_OF_RANGE();
    error REQUEST_IS_NOT_WITHIN_ACCEPTED_RANGE();
    error REWARD_WITHDRAWAL_TYPE_C_ERROR(string);
    error ACTION_WOULD_TAKE_POOL_REWARDS_BELOW_CONVERSATION_LIMIT();
    error LIQUIDITY_IS_CURRENTLY_BELOW_CONVERSATION_LIMIT();
    error LIQUIDITY_RATIO_DURING_RESET_OF_OPTIMAL_RATIO_CANNOT_BE_GREATER_THAN_THE_OPTIMAL_RATIO();
    error REQESTOR_IS_NOT_THE_OWNER_OF_THIS_POSITION();
    error CANNOT_WITHDRAW_ZERO_ASSET_FROM_POOL();
    error INSUFFICENT_POSITION_BALANCE();
    error ACCOUNT_IS_ALREADY_POOL_MANAGER();
    error ACCOUNT_IS_NOT_A_POOL_MANAGER();
    error BOUNTY_DEPOSIT_NOT_RECOGNIZED();
    error REWARD_IS_NOT_BOUNTY_REWARD();
    error INSUFFICIENT_BOUNTY_REWARD();
    error BRAND_DOES_NOT_EXIST();
    error BRAND_ALREADY_EXISTS();
    error REWARD_DOES_NOT_EXIST();
    error REWARD_ALREADY_EXISTS();
    error REWARD_ALREADY_OPEN();
    error REWARD_IS_NOT_OPEN();
    error ACCOUNT_IS_NOT_TIED_TO_ANY_BRAND();
    error REQUESTOR_IS_NOT_REWARD_ISSUER();
    error REWARD_DOES_NOT_SUPPORT_BOUNTIES();
    error REWARD_ALREADY_SUPPORT_BOUNTIES();
    error INSUFFICIENT_BOUNTY_REWARD_BALANCE();
    error INSUFFICIENT_TREASURY_REWARD_BALANCE();
    error INSUFFICIENT_BRAND_ME_TREASURY_BALANCE();
    error ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
    error ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_BOUNTY_REQUEST();
    error ACCOUNT_ALREADY_HAS_ACCESS();
    error REQUESTOR_IS_NOT_ADMIN_FOR_THIS_ACCESS_KEY();
    error ACCESS_KEY_ALREADY_EXISTS_PLEASE_CHANGE_INSTEAD();
    error ACCOUNT_DOES_NOT_HAVE_ACCESS();
    error REWARDS_TRANSFER_FAILED();
    error REWARDS_PERMIT_FAILED();
    error BOUNTY_POOL_IS_CURRENTLY_BUSY();
    error BOTH_DEPOSITS_CAN_NOT_BE_ZERO();
    error TREASURY_DEPOSIT_NOT_RECOGNIZED();
    error BRAND_ID_CANNOT_BE_EMPTY();
    error BOTH_WITHDRAWALS_CANNOT_BE_ZERO();
    error INSUFFICIENT_TREASURY_ME_BALANCE();
    error TREASURY_IS_CURRENTLY_BUSY();
    error BOTH_TOP_UPS_CANNOT_BE_ZERO();
    error SEEDS_ARE_TOO_MUCH();
    error INCOHERENT_TARGET_AND_SEED_LENGTH();
    error PLEASE_READ_TERMS_AND_CONDITIONS();
    error REWARD_NAME_CANNOT_BE_EMPTY();
    error REWARD_SYMBOL_CANNOT_BE_EMPTY();
    error ACCOUNT_IS_NOT_REGISTERED_AS_A_BRAND();
    error INVALID_POSITION();
    error INSUFFICIENT_REWARD_POSITION();
    error INSUFFICIENT_ME_POSITION();
    error REQUESTOR_IS_NOT_OWNER_OF_POSITION();
    error CONVERSATION_WILL_CAUSE_OPEN_REWARDS_TO_GO_OUT_OF_RANGE();
    error ACTION_WILL_TAKE_POOL_ME_TOKENS_BELOW_CONVERSATION_LIMIT();
    error INSUFFICENT_REWARD_AMOUNT_DEPOSITED_FOR_CONVERSATION();
    error R_OPTIMAL_CANNOT_BE_ZERO();
    error REQUESTOR_HAS_NO_POSITION();
    error POSITIONS_ARE_MORE_THAN_TWENTY_TRY_GETTING_THEM_ONE_AT_A_TIME();
    error REQUEST_NOT_WITHIN_SLIPPAGE_RANGE();
    error POOL_IS_BUSY();
    error INVALID_POSITION_INDEX();
    error REQUESTOR_DOES_NOT_IMPLEMENT_OPEN_REWARDS();
    error CONVERSATION_FAILED();
    error NOT_OPEN_REWARDS_CONVERSATION();
    error INSUFFICIENT_DEPOSIT();
    error INSUFFICIENT_REWARD();
    error ALREADY_INITIALIZED();
    error REWARDS_APPROVAL_FAILED();
    error ACCOUNT_IS_ALREADY_REGISTERED_AS_A_BRAND();
    error NOT_AUTHORIZED_TO_MANAGER_RUNTIME();
    error BATCH_PROOF_ALREADY_SET();
    error VAULT_SIGNATURE_USED();
    error VAULT_INVALID_SIGNATURE();
    error VAULT_INVALID_ALLOWEE();
    error SIGNER_IS_NOT_RUNTIME();
    error VAULT_INVALID_HASH();
    error BRAND_ID_IS_ALREADY_TAKEN();
    error PERMIT_DEADLINE_EXPIRED();
    error ME_AMOUNT_CAN_NOT_BE_EQUAL_TO_PERMIT_AMOUNT();
    error VAULT_EXPIRED_SIGNATURE();
    error INVALID_INPUT();
    error OPEN_REWARDS_ALREADY_INITIALIZED();

    // Main (diamonds) errors

    string public constant CALLER_IS_NOT_CONTRACT_OWNER = "1";
    string public constant INCORRECT_UPGRADE_ACTION = "2";
    string public constant NO_SELECTOR_IN_SPECIFIED_MODULE = "3";
    string public constant ZERO_ADDRESS_NOT_ALLOWED = "4";
    string public constant MODULE_ALREADY_EXISTS = "5";
    string public constant MODULE_IS_SAME_AS_THAT_TO_BE_REPLACED = "6";
    string public constant REMOVE_MODULE_ADDRESS_MUST_BE_ZERO_ADDRESS = "7";
    string public constant SERVICE_OR_PROVIDER_DOES_NOT_EXIST = "8";
    string public constant CAN_NOT_REMOVE_THIS_SERVICE_OR_PROVIDER = "9";
    string public constant INIT_ADDRESS_HAS_NO_CODE = "10";
    string public constant MODULE_DOES_NOT_EXIST = "11";
    string public constant DELEGATE_CALL_NOT_ALLOWED = "12";
}

File 9 of 12 : validators.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Errors} from "./errors.sol";

library Validator {
    function ensureAddressIsNotZeroAddress(address _addr) internal pure {
        if (_addr == address(0)) {
            revert Errors.ADDRESS_ZERO_NOT_ALLOWED();
        }
    }

    function ensureValueIsNotZero(uint256 _value) internal pure {
        if (_value == 0) {
            revert Errors.ZERO_NOT_ALLOWED();
        }
    }

    function ensureInputIsNotEmpty(string memory _stringOpt) internal pure {
        if (bytes(_stringOpt).length == 0) {
            revert Errors.EMPTY_STRING_NOT_ALLOWED();
        }
    }

    function ensureReasonIsNotEmpty(bytes32 input) internal pure {
        if (input == bytes32(0)) revert Errors.EMPTY_REASON_NOT_ALLOWED();
    }

    function ensureBrandIdIsNotEmpty(bytes10 brandId) internal pure {
        if (brandId == bytes10(0)) {
            revert Errors.BRAND_ID_CANNOT_BE_EMPTY();
        }
    }

    function ensureRIsWithinAcceptableRange(uint256 r, uint256 rMaxLimit) internal pure {
        if (r > rMaxLimit) {
            revert Errors.CONVERSATION_WILL_CAUSE_POOL_TO_GO_OUT_OF_RANGE();
        }
    }

    function isEmpty(string memory _data) internal pure returns (bool) {
        return bytes(_data).length == 0;
    }

    function isEmpty(bytes10 brandId) internal pure returns (bool) {
        return brandId == bytes10(0);
    }

    function isEmptyB(bytes32 brandId) internal pure returns (bool) {
        return brandId == bytes32(0);
    }

    function isEmpty(uint256[] memory myArray) internal pure returns (bool) {
        return myArray.length == 0;
    }

    function isZero(uint256 _data) internal pure returns (bool) {
        return _data == 0;
    }

    function isFalse(bool _data) internal pure returns (bool) {
        return _data == false;
    }
}

File 10 of 12 : constants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library Constants {
    uint256 constant PRECISION = 1000000;
    uint256 constant GOLDEN_RATIO_IN_PRECISION = (1618 * PRECISION) / 100;
    uint256 constant EXCHANGE_SLOPE = GOLDEN_RATIO_IN_PRECISION / 2;
    uint256 constant STARTING_SEED = 1;
    uint256 constant EMPTY_POSITION = 0;
    bytes10 constant DEFAULT_BRAND_ID = bytes10(0);
    bytes32 constant EMPTY_ACCESS_KEY = bytes32(0);
    bytes32 constant CAI = keccak256("customer acquisition incentives");
    bytes32 constant PROTOCOL_FEES = keccak256("protocol fees");
    bytes32 constant GAS_COSTS = keccak256("gas costs");
    uint256 constant PERCENTAGE = 100;
    bytes32 constant NORMAL = keccak256("normal");
    bytes32 constant WITH_REWARDS_IF_NEED_BE = keccak256("with rewards");
    bytes32 constant WITHDRAWABLE = keccak256("withdrawable");
    bytes32 constant FORCED = keccak256("forced");
    string constant ME_PROTOCOL = "me protocol";
    string constant ME_P = "MeP";
    bytes4 constant OPEN_REWARDS = bytes4(keccak256("openrewards secret"));
    uint8 constant FUNGIBLE_TYPE_A = 1;
    string constant EMPTY_STRING = "";
    uint256 constant EMPTY_AMOUNT = 0;
    address constant ME_DISPENSER = 0x1111111111111111111111111111111111111111;
}

File 11 of 12 : roleguard.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Database} from "./database.sol";
import {Errors} from "./errors.sol";
import {Validator} from "./validators.sol";
import {Params} from "./params.sol";
import {Constants} from "./constants.sol";
import {Roles} from "./roles.sol";

library RoleGuard {
    struct AccessData {
        bytes32 adminAccessKey;
        mapping(address => bool) members;
    }

    function writableRoleRecords()
        internal
        pure
        returns (mapping(bytes32 => AccessData) storage records)
    {
        bytes32 position = Database.ACCESS_RECORDS;
        assembly {
            records.slot := position
        }
    }

    function isAuthorized(
        bytes32 accessKey,
        address account
    ) internal view returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        return records[accessKey].members[account];
    }

    ///@dev many seeds, single reward with brandId input
    function ensureAccountIsAuthorized(
        address target,
        bytes32[] memory seeds,
        address account,
        bytes10 brandId
    ) internal view returns (bool) {
        if (seeds.length > 5) revert Errors.SEEDS_ARE_TOO_MUCH();
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();

        if (!Validator.isEmpty(brandId)) {
            (
                bytes32 adminAccessKey,
                bytes32 accessKey
            ) = synthesizeAdminAndAccessKeyForReward(brandId, target, seeds[0]);
            if (adminAccessKey == records[accessKey].adminAccessKey) {
                return true;
            }
        }
        for (uint256 i; i < seeds.length; ) {
            bytes32 accessKey = synthesizeAccessKeyForReward(target, seeds[i]);
            if (records[accessKey].members[account]) {
                return true;
            }
            ++i;
        }
        revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
    }

    ///@dev many seeds, with brandId target
    function ensureAccountIsAuthorized(
        bytes10 target,
        bytes32[] memory seeds,
        address account,
        bytes10 brandId
    ) internal view returns (bool) {
        if (seeds.length > 5) revert Errors.SEEDS_ARE_TOO_MUCH();
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (!Validator.isEmpty(brandId)) {
            if (target == brandId) return true;
        }
        for (uint256 i; i < seeds.length; ) {
            bytes32 accessKey = synthesizeAccessKeyForBrand(target, seeds[i]);
            if (records[accessKey].members[account]) {
                return true;
            }
            ++i;
        }
        revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
    }

    ///@dev used with openRewards
    function ensureAccountIsAuthorized(
        address target,
        bytes32[] memory seeds,
        address account
    ) internal view returns (bool) {
        if (seeds.length > 5) revert Errors.SEEDS_ARE_TOO_MUCH();
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();

        (
            bytes32 adminAccessKey,
            bytes32 _accessKey
        ) = synthesizeAdminAndAccessKeysForOpenRewards(
                account,
                target,
                seeds[0]
            );
        if (adminAccessKey == records[_accessKey].adminAccessKey) return true;

        for (uint256 i; i < seeds.length; ) {
            bytes32 accessKey = synthesizeAccessKeyForReward(target, seeds[i]);
            if (records[accessKey].members[account]) {
                return true;
            }
            ++i;
        }
        revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
    }

    ///@dev single seed, single reward with brand id
    function ensureAccountIsAuthorized(
        address target,
        bytes32 seed,
        address account,
        bytes10 brandId
    ) internal view returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        (
            bytes32 adminKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeyForReward(brandId, target, seed);
        if (adminKey != records[accessKey].adminAccessKey) {
            if (!records[accessKey].members[account]) {
                revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
            }
        }
        return true;
    }

    ///@dev single seed, single target brand with brand id
    function ensureAccountIsAuthorized(
        bytes10 target,
        bytes32 seed,
        address account,
        bytes10 brandId
    ) internal view returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (brandId != target) {
            bytes32 accessKey = synthesizeAccessKeyForBrand(target, seed);
            if (!records[accessKey].members[account]) {
                revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
            }
        }
        return true;
    }

    ///@dev used for openrewards
    function ensureAccountIsAuthorized(
        address target,
        bytes32 seed,
        address account
    ) internal view returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();

        (
            bytes32 adminAccessKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeysForOpenRewards(account, target, seed);
        if (adminAccessKey == records[accessKey].adminAccessKey) return true;
        if (records[accessKey].members[account]) return true;
        revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
    }

    ///@dev this is used foe the main me-protocol rule
    function ensureAccountIsAuthorized(
        bytes32 seed,
        address account
    ) internal view returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();

        (
            bytes32 adminAccessKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeyForMeProtocol(account, seed);
        if (adminAccessKey == records[accessKey].adminAccessKey) return true;
        if (records[accessKey].members[account]) return true;
        revert Errors.ACCOUNT_IS_NOT_AUTHORIZED_TO_MAKE_THIS_REQUEST();
    }

    function grantAccessToAccount(
        bytes32 accessKey,
        bytes32 adminAccessKey,
        address account
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (adminAccessKey != records[accessKey].adminAccessKey) {
            revert Errors.REQUESTOR_IS_NOT_ADMIN_FOR_THIS_ACCESS_KEY();
        }
        if (records[accessKey].members[account]) {
            revert Errors.ACCOUNT_ALREADY_HAS_ACCESS();
        }
        records[accessKey].members[account] = true;
        return true;
    }

    function revokeAccessFromAccount(
        bytes32 accessKey,
        bytes32 adminAccessKey,
        address account
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (adminAccessKey != records[accessKey].adminAccessKey) {
            revert Errors.REQUESTOR_IS_NOT_ADMIN_FOR_THIS_ACCESS_KEY();
        }
        if (!records[accessKey].members[account]) {
            revert Errors.ACCOUNT_DOES_NOT_HAVE_ACCESS();
        }
        records[accessKey].members[account] = false;
        return true;
    }

    function createNewAccesskeyForReward(
        bytes10 brand,
        address target,
        bytes32 seed
    ) internal returns (bool) {
        (
            bytes32 adminAccessKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeyForReward(brand, target, seed);
        return _createNewAccessKey(accessKey, adminAccessKey);
    }

    function createNewAccessKeysForReward(
        bytes10 brand,
        address target,
        bytes32[] memory seeds
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (seeds.length > 5) revert Errors.SEEDS_ARE_TOO_MUCH();
        for (uint256 i; i < seeds.length; ) {
            (
                bytes32 adminAccessKey,
                bytes32 accessKey
            ) = synthesizeAdminAndAccessKeyForReward(brand, target, seeds[i]);
            if (
                records[accessKey].adminAccessKey != Constants.EMPTY_ACCESS_KEY
            ) {
                revert Errors.ACCESS_KEY_ALREADY_EXISTS_PLEASE_CHANGE_INSTEAD();
            }
            records[accessKey].adminAccessKey = adminAccessKey;
            ++i;
        }
        return true;
    }

    function createNewAccessKeysForOpenRewards(
        address admin,
        address target,
        bytes32[] memory seeds
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (seeds.length > 5) revert Errors.SEEDS_ARE_TOO_MUCH();
        for (uint256 i; i < seeds.length; ) {
            (
                bytes32 adminAccessKey,
                bytes32 accessKey
            ) = synthesizeAdminAndAccessKeysForOpenRewards(
                    admin,
                    target,
                    seeds[i]
                );
            if (
                records[accessKey].adminAccessKey != Constants.EMPTY_ACCESS_KEY
            ) {
                revert Errors.ACCESS_KEY_ALREADY_EXISTS_PLEASE_CHANGE_INSTEAD();
            }
            records[accessKey].adminAccessKey = adminAccessKey;
            ++i;
        }
        return true;
    }

    function createNewAccessKeyForMeProtocol(
        address admin,
        bytes32[] memory seed
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (seed.length > 5) revert Errors.SEEDS_ARE_TOO_MUCH();
        for (uint256 i; i < seed.length; ) {
            (
                bytes32 adminAccessKey,
                bytes32 accessKey
            ) = synthesizeAdminAndAccessKeyForMeProtocol(admin, seed[i]);
            if (
                records[accessKey].adminAccessKey != Constants.EMPTY_ACCESS_KEY
            ) {
                revert Errors.ACCESS_KEY_ALREADY_EXISTS_PLEASE_CHANGE_INSTEAD();
            }
            records[accessKey].adminAccessKey = adminAccessKey;
            ++i;
        }

        return true;
    }

    function createNewAccessKeyForMeProtocol(
        address admin,
        bytes32 seed
    ) internal returns (bool) {
        (
            bytes32 adminAccessKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeyForMeProtocol(admin, seed);
        return _createNewAccessKey(accessKey, adminAccessKey);
    }

    function createNewAccesskeyForBrand(
        bytes10 brand,
        bytes32 seed
    ) internal returns (bool) {
        (
            bytes32 adminAccessKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeyForBrand(brand, seed);
        return _createNewAccessKey(accessKey, adminAccessKey);
    }

    function createNewAccessKeyForOpenRewards(
        address admin,
        address target,
        bytes32 seed
    ) internal returns (bool) {
        (
            bytes32 adminAccessKey,
            bytes32 accessKey
        ) = synthesizeAdminAndAccessKeysForOpenRewards(admin, target, seed);
        return _createNewAccessKey(accessKey, adminAccessKey);
    }

    function _createNewAccessKey(
        bytes32 accessKey,
        bytes32 adminAccessKey
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (records[accessKey].adminAccessKey != Constants.EMPTY_ACCESS_KEY) {
            revert Errors.ACCESS_KEY_ALREADY_EXISTS_PLEASE_CHANGE_INSTEAD();
        }
        records[accessKey].adminAccessKey = adminAccessKey;
        return true;
    }

    function changeAdminAccessKey(
        bytes32 accessKey,
        bytes32 adminAccessKey,
        bytes32 newAdminAccessKey
    ) internal returns (bool) {
        mapping(bytes32 => AccessData) storage records = writableRoleRecords();
        if (adminAccessKey != records[accessKey].adminAccessKey) {
            revert Errors.REQUESTOR_IS_NOT_ADMIN_FOR_THIS_ACCESS_KEY();
        }
        records[accessKey].adminAccessKey = newAdminAccessKey;
        return true;
    }

    function synthesizeAdminAndAccessKeyForMeProtocol(
        address admin,
        bytes32 seed
    ) internal pure returns (bytes32 adminAccessKey, bytes32 accessKey) {
        accessKey = synthesizeAccessKeyForMeProtocol(seed);
        adminAccessKey = synthesizeAdminAccessKeyForMeProtocol(admin, seed);
    }

    function synthesizeAdminAndAccessKeyForReward(
        bytes10 brand,
        address target,
        bytes32 seed
    ) internal pure returns (bytes32 adminAccessKey, bytes32 accessKey) {
        accessKey = synthesizeAccessKeyForReward(target, seed);
        adminAccessKey = synthesizeAdminAccessKeyForReward(brand, target);
    }

    function synthesizeAdminAndAccessKeyForBrand(
        bytes10 brand,
        bytes32 seed
    ) internal pure returns (bytes32 adminAccessKey, bytes32 accessKey) {
        accessKey = synthesizeAccessKeyForBrand(brand, seed);
        adminAccessKey = synthesizeAdminAcessKeyForBrand(brand);
    }

    function synthesizeAccessKeyForReward(
        address target,
        bytes32 seed
    ) internal pure returns (bytes32 accessKey) {
        accessKey = keccak256(abi.encodePacked(target, seed));
    }

    function synthesizeAccessKeyForOpenRewards(
        address target,
        bytes32 seed
    ) internal pure returns (bytes32 accessKey) {
        accessKey = keccak256(abi.encodePacked(target, seed));
    }

    function synthesizeAdminAccessKeyForOpenRewards(
        address admin,
        address target
    ) internal pure returns (bytes32 adminAccessKey) {
        adminAccessKey = keccak256(abi.encodePacked(admin, target));
    }

    function synthesizeAdminAcessKeyForBrand(
        bytes10 brand
    ) internal pure returns (bytes32 adminAccessKey) {
        adminAccessKey = keccak256(abi.encodePacked(brand));
    }

    function synthesizeAdminAccessKeyForMeProtocol(
        address admin,
        bytes32 seed
    ) internal pure returns (bytes32 accessKey) {
        accessKey = keccak256(abi.encodePacked(admin, seed));
    }

    function synthesizeAccessKeyForMeProtocol(
        bytes32 seed
    ) internal pure returns (bytes32 adminAccessKey) {
        adminAccessKey = keccak256(abi.encodePacked(seed));
    }

    function synthesizeAdminAccessKeyForReward(
        bytes32 brand,
        address target
    ) internal pure returns (bytes32 adminAccessKey) {
        adminAccessKey = keccak256(abi.encodePacked(brand, target));
    }

    function synthesizeAccessKeyForBrand(
        bytes10 brand,
        bytes32 seed
    ) internal pure returns (bytes32 accessKey) {
        accessKey = keccak256(abi.encodePacked(brand, seed));
    }

    function synthesizeAdminAndAccessKeysForOpenRewards(
        address admin,
        address target,
        bytes32 seed
    ) internal pure returns (bytes32 adminAccessKey, bytes32 accessKey) {
        accessKey = synthesizeAccessKeyForOpenRewards(target, seed);
        adminAccessKey = synthesizeAdminAccessKeyForOpenRewards(admin, target);
    }
}

File 12 of 12 : roles.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library Roles {
    // protocol based roles
    bytes32 internal constant PROTOCOL = keccak256("PROTOCOL");
    bytes32 internal constant PROTOCOL_ADMIN = keccak256("PROTOCOL_ADMIN");
    bytes32 internal constant LIQUIDITY_MANAGER = keccak256("LIQUIDITY_MANAGER");
    bytes32 internal constant ONBOARDING_MANAGER = keccak256("ONBOARDING_MANAGER");

    // brand based roles
    bytes32 internal constant BRAND = keccak256("BRAND");
    bytes32 internal constant BRAND_ACCOUNT_MANAGER = keccak256("BRAND_ACCOUNT_MANAGER");
    bytes32 internal constant BOUNTY_MANAGER = keccak256("BOUNTY_MANAGER");
    bytes32 internal constant TREASURY_MANAGER = keccak256("TREASURY_MANAGER");

    // pool based roles
    bytes32 internal constant OPEN_REWARDS_MANAGER = keccak256("OPEN_REWARDS_MANAGER");

    // reward based roles
    bytes32 internal constant REWARD_MANAGER = keccak256("REWARD_MANAGER");

    // auto top-up based roles
    bytes32 internal constant AUTO_TOP_UP_MANAGER = keccak256("AUTO_TOP_UP_MANAGER");
}

Settings
{
  "remappings": [
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "@openzeppelin/=lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_upgrader","type":"address"},{"components":[{"internalType":"address","name":"meId","type":"address"},{"internalType":"address","name":"bountyId","type":"address"},{"internalType":"address","name":"treasuryId","type":"address"},{"internalType":"address","name":"vaultId","type":"address"},{"internalType":"bytes10","name":"adminId","type":"bytes10"}],"internalType":"struct Params.EditableProtocolRecords","name":"newRecord","type":"tuple"}],"stateMutability":"payable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"moduleAddress","type":"address"},{"internalType":"enum Data.UpgradeAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct Data.UpgradeDetails[]","name":"_upgradeDetails","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]

60806040526040516113a13803806113a183398101604081905261002291610ed1565b61002b83610233565b80517f196d3c88e74e7f2487f8924437cb2915a3cb6c9a960241d7fe9409f01cab8a8480546001600160a01b03199081166001600160a01b039384161790915560208301517f196d3c88e74e7f2487f8924437cb2915a3cb6c9a960241d7fe9409f01cab8a858054831691841691909117905560408301517f196d3c88e74e7f2487f8924437cb2915a3cb6c9a960241d7fe9409f01cab8a868054831691841691909117905560808301517f196d3c88e74e7f2487f8924437cb2915a3cb6c9a960241d7fe9409f01cab8a87805460608601516001600160f01b0319909116600160a01b60b09490941c939093029093169190911791909216179055604080516001808252818301909252600091816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908161013e5750506040805160018082528183019092529192506000919060208083019080368337019050509050635298e42c60e01b816000815181106101ad576101ad610fa5565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b03861681529081016000815260200182815250826000815181106101fd576101fd610fa5565b6020026020010181905250610229826000604051806020016040528060008152506102b660201b60201c565b505050505061120f565b7f5078ef9c484590d0aa6db71c8ae4749dfaf00e932668b2dd28a3daff0481c3bc80546001600160a01b031981166001600160a01b0384811691821790935560405160008051602061135d833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b835181101561046e5760008482815181106102d6576102d6610fa5565b6020026020010151602001519050600060028111156102f7576102f7610fbb565b81600281111561030957610309610fbb565b0361035d5761035885838151811061032357610323610fa5565b60200260200101516000015186848151811061034157610341610fa5565b6020026020010151604001516104b960201b60201c565b61045b565b600181600281111561037157610371610fbb565b036103c05761035885838151811061038b5761038b610fa5565b6020026020010151600001518684815181106103a9576103a9610fa5565b6020026020010151604001516106cb60201b60201c565b60028160028111156103d4576103d4610fbb565b03610423576103588583815181106103ee576103ee610fa5565b60200260200101516000015186848151811061040c5761040c610fa5565b6020026020010151604001516108e360201b60201c565b60408051808201825260018152601960f91b6020820152905162461bcd60e51b81526104529190600401611021565b60405180910390fd5b508061046681611051565b9150506102b9565b507f325e201380567746a856a988c1dc97502c1e43623b000b9cac993f6bc85e51358383836040516104a29392919061106a565b60405180910390a16104b482826109ea565b505050565b6000815111604051806040016040528060018152602001603360f81b815250906104f65760405162461bcd60e51b81526004016104529190611021565b506040805180820190915260018152600d60fa1b602082015260008051602061135d833981519152906001600160a01b0384166105465760405162461bcd60e51b81526004016104529190611021565b506001600160a01b0383166000908152600182016020526040812054906001600160601b038216900361057d5761057d8285610ab8565b60005b83518110156106c457600084828151811061059d5761059d610fa5565b6020908102919091018101516001600160e01b03198116600090815286835260409081902054815180830190925260018252603560f81b938201939093529092506001600160a01b039091169081156106095760405162461bcd60e51b81526004016104529190611021565b506001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b031916179055836106ac8161116a565b945050505080806106bc90611051565b915050610580565b5050505050565b6000815111604051806040016040528060018152602001603360f81b815250906107085760405162461bcd60e51b81526004016104529190611021565b506040805180820190915260018152600d60fa1b602082015260008051602061135d833981519152906001600160a01b0384166107585760405162461bcd60e51b81526004016104529190611021565b506001600160a01b0383166000908152600182016020526040812054906001600160601b038216900361078f5761078f8285610ab8565b60005b83518110156106c45760008482815181106107af576107af610fa5565b6020908102919091018101516001600160e01b03198116600090815286835260409081902054815180830190925260018252601b60f91b938201939093529092506001600160a01b03918216918816820361081d5760405162461bcd60e51b81526004016104529190611021565b50610829858284610b22565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b031916179055836108cb8161116a565b945050505080806108db90611051565b915050610792565b6000815111604051806040016040528060018152602001603360f81b815250906109205760405162461bcd60e51b81526004016104529190611021565b506040805180820190915260018152603760f81b602082015260008051602061135d833981519152906001600160a01b038416156109715760405162461bcd60e51b81526004016104529190611021565b5060005b82518110156109e457600083828151811061099257610992610fa5565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b03166109cf848284610b22565b505080806109dc90611051565b915050610975565b50505050565b6001600160a01b0382166109fc575050565b610a268260405180604001604052806002815260200161031360f41b815250610e7c60201b60201c565b600080836001600160a01b031683604051610a419190611198565b600060405180830381855af49150503d8060008114610a7c576040519150601f19603f3d011682016040523d82523d6000602084013e610a81565b606091505b5091509150816109e457805115610a9b5780518082602001fd5b838360405163192105d760e01b81526004016104529291906111b4565b610ada8160405180606001604052806024815260200161137d60249139610e7c565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6040805180820190915260018152600760fb1b60208201526001600160a01b038316610b615760405162461bcd60e51b81526004016104529190611021565b506040805180820190915260018152603960f81b60208201526001600160a01b0383163003610ba35760405162461bcd60e51b81526004016104529190611021565b506001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b03169291610bf3916111e0565b9050808214610ce5576001600160a01b03841660009081526001860160205260408120805483908110610c2857610c28610fa5565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110610c7957610c79610fa5565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480610d0e57610d0e6111f9565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b031985168252869052604081208190558190036106c4576002850154600090610d71906001906111e0565b6001600160a01b0386166000908152600180890160205260409091200154909150808214610e20576000876002018381548110610db057610db0610fa5565b6000918252602090912001546002890180546001600160a01b039092169250829184908110610de157610de1610fa5565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480610e3357610e336111f9565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b81816109e45760405162461bcd60e51b81526004016104529190611021565b80516001600160a01b0381168114610eb457600080fd5b919050565b80516001600160b01b031981168114610eb457600080fd5b600080600083850360e0811215610ee757600080fd5b610ef085610e9d565b9350610efe60208601610e9d565b925060a0603f1982011215610f1257600080fd5b5060405160a081016001600160401b0381118282101715610f4357634e487b7160e01b600052604160045260246000fd5b8060405250610f5460408601610e9d565b8152610f6260608601610e9d565b6020820152610f7360808601610e9d565b6040820152610f8460a08601610e9d565b6060820152610f9560c08601610eb9565b6080820152809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60005b83811015610fec578181015183820152602001610fd4565b50506000910152565b6000815180845261100d816020860160208601610fd1565b601f01601f19169290920160200192915050565b6020815260006110346020830184610ff5565b9392505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016110635761106361103b565b5060010190565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101561113a57898403607f19018652815180516001600160a01b031685528381015189860190600381106110d957634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156111255783516001600160e01b03191682529286019260019290920191908601906110fb565b50978501979550505090820190600101611093565b50506001600160a01b038a1690880152868103604088015261115c8189610ff5565b9a9950505050505050505050565b60006001600160601b038281166002600160601b0319810161118e5761118e61103b565b6001019392505050565b600082516111aa818460208701610fd1565b9190910192915050565b6001600160a01b03831681526040602082018190526000906111d890830184610ff5565b949350505050565b818103818111156111f3576111f361103b565b92915050565b634e487b7160e01b600052603160045260246000fd5b61013f8061121e6000396000f3fe60806040523661000b57005b600080356001600160e01b03191681527f5078ef9c484590d0aa6db71c8ae4749dfaf00e932668b2dd28a3daff0481c3b860208181526040928390205483518085019094526002845261313160f01b91840191909152909182916001600160a01b031690816100965760405162461bcd60e51b815260040161008d91906100bb565b60405180910390fd5b503660008037600080366000845af43d6000803e8080156100b6573d6000f35b3d6000fd5b600060208083528351808285015260005b818110156100e8578581018301518582016040015282016100cc565b506000604082860101526040601f19601f830116850101925050509291505056fea2646970667358221220e4fdb85907ca53cdd5fa360c88c313ed6194813eb8681cdaa4dd75603ffb031364736f6c634300081500335078ef9c484590d0aa6db71c8ae4749dfaf00e932668b2dd28a3daff0481c3b84c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64650000000000000000000000005c919bcdda25447c168c87252326a43c709ecdbd000000000000000000000000bbec5e0eb165d6ea898253a00f42493ad7b26bc200000000000000000000000047dfb1d5aa71466685f33d918666d534821083a50000000000000000000000008c270a0227aef88da2616d822d61b32bd8fe1f4700000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a245139b4b1d4a24a548efd781e939ae9a4a13161646d696e000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040523661000b57005b600080356001600160e01b03191681527f5078ef9c484590d0aa6db71c8ae4749dfaf00e932668b2dd28a3daff0481c3b860208181526040928390205483518085019094526002845261313160f01b91840191909152909182916001600160a01b031690816100965760405162461bcd60e51b815260040161008d91906100bb565b60405180910390fd5b503660008037600080366000845af43d6000803e8080156100b6573d6000f35b3d6000fd5b600060208083528351808285015260005b818110156100e8578581018301518582016040015282016100cc565b506000604082860101526040601f19601f830116850101925050509291505056fea2646970667358221220e4fdb85907ca53cdd5fa360c88c313ed6194813eb8681cdaa4dd75603ffb031364736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000005c919bcdda25447c168c87252326a43c709ecdbd000000000000000000000000bbec5e0eb165d6ea898253a00f42493ad7b26bc200000000000000000000000047dfb1d5aa71466685f33d918666d534821083a50000000000000000000000008c270a0227aef88da2616d822d61b32bd8fe1f4700000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a245139b4b1d4a24a548efd781e939ae9a4a13161646d696e000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _admin (address): 0x5c919BCddA25447C168C87252326A43C709ECdBD
Arg [1] : _upgrader (address): 0xBbEC5E0EB165D6eA898253A00f42493AD7B26bc2
Arg [2] : newRecord (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c919bcdda25447c168c87252326a43c709ecdbd
Arg [1] : 000000000000000000000000bbec5e0eb165d6ea898253a00f42493ad7b26bc2
Arg [2] : 00000000000000000000000047dfb1d5aa71466685f33d918666d534821083a5
Arg [3] : 0000000000000000000000008c270a0227aef88da2616d822d61b32bd8fe1f47
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000002a245139b4b1d4a24a548efd781e939ae9a4a131
Arg [6] : 61646d696e000000000000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.