Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/booster/pro/MultiSigBoosterPro.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "../../interface/IBoosterPro.sol";
/// @title MultiSigBoosterPro
contract MultiSigBoosterPro {
address[3] public admins;
IBoosterPro public boosterPro;
mapping(bytes32 => mapping(address => bool)) public approvals;
bytes32 public currentPendingAction;
uint8 public approvalCount;
/// @dev Errors
error NotAdmin();
error AlreadyApproved();
error InsufficientApprovals();
error InvalidAdminIndex();
error AdminExists();
error ZeroAddress();
/// @dev Events
event AdminUpdated(uint256 indexed index, address oldAdmin, address newAdmin);
event ActionApproved(bytes32 indexed actionId, address indexed admin, uint8 count);
event EmergencyWithdrawToken(address indexed to, uint256 amount);
event EmergencyWithdrawBonds(address to, uint256[] tokenIds);
modifier onlyAdmins() {
if (msg.sender != admins[0] && msg.sender != admins[1] && msg.sender != admins[2]) revert NotAdmin();
_;
}
constructor(address _admin1, address _admin2, address _admin3, address _boosterPro) {
admins = [_admin1, _admin2, _admin3];
boosterPro = IBoosterPro(_boosterPro);
}
function _approveAction(bytes32 actionId) internal {
if (approvals[actionId][msg.sender]) revert AlreadyApproved();
approvals[actionId][msg.sender] = true;
approvalCount += 1;
emit ActionApproved(actionId, msg.sender, approvalCount);
}
function _startAction(bytes32 actionId) internal{
if (actionId != currentPendingAction) {
if (currentPendingAction != bytes32(0)) {
approvals[actionId][admins[0]] = false;
approvals[actionId][admins[1]] = false;
approvals[actionId][admins[2]] = false;
}
currentPendingAction = actionId;
approvalCount = 0;
}
}
function _clearAction(bytes32 actionId) internal {
approvals[actionId][admins[0]] = false;
approvals[actionId][admins[1]] = false;
approvals[actionId][admins[2]] = false;
currentPendingAction = bytes32(0);
approvalCount = 0;
}
function changeAdmin(uint256 index, address newAdmin) external onlyAdmins {
if (index >= 3) revert InvalidAdminIndex();
if (newAdmin == address(0)) revert ZeroAddress();
if (newAdmin == admins[0] || newAdmin == admins[1] || newAdmin == admins[2]) revert AdminExists();
bytes32 actionId = keccak256(abi.encodePacked("changeAdmin", index, newAdmin));
_startAction(actionId);
_approveAction(actionId);
if (approvalCount == 3) {
address old = admins[index];
admins[index] = newAdmin;
emit AdminUpdated(index, old, newAdmin);
_clearAction(actionId);
}
}
function emergencyWithdrawToken(address to, uint256 amount) external onlyAdmins {
if (to != admins[0] && to != admins[1] && to != admins[2]) revert NotAdmin();
bytes32 actionId = keccak256(abi.encodePacked("emergencyWithdrawToken", to, amount));
_startAction(actionId);
_approveAction(actionId);
if (approvalCount == 2) {
boosterPro.emergencyWithdrawToken(to, amount);
emit EmergencyWithdrawToken(to, amount);
_clearAction(actionId);
}
}
function emergencyWithdrawBonds(address to, uint256[] calldata tokenIds) external onlyAdmins {
if (to != admins[0] && to != admins[1] && to != admins[2]) revert NotAdmin();
bytes32 actionId = keccak256(abi.encodePacked("emergencyWithdrawBonds", to, tokenIds));
_startAction(actionId);
_approveAction(actionId);
if (approvalCount == 2) {
boosterPro.emergencyWithdrawBonds(to, tokenIds);
emit EmergencyWithdrawBonds(to, tokenIds);
_clearAction(actionId);
}
}
function setActive(bool enable) external onlyAdmins {
boosterPro.setActive(enable);
}
function setMaxBondsPerAddress(uint256 value) external onlyAdmins {
boosterPro.setMaxBondsPerAddress(value);
}
function setPowers(uint256[3] calldata powers) external onlyAdmins {
boosterPro.setPowers(powers);
}
function setProportionEarn(bool isMin, uint256 value) external onlyAdmins {
boosterPro.setProportionEarn(isMin, value);
}
function setBoostingRate(bool isMin, uint256 value) external onlyAdmins {
boosterPro.setBoostingRate(isMin, value);
}
function setDisableUser(address user, bool disable) external onlyAdmins {
boosterPro.setDisableUser(user,disable);
}
function setIntervalLimit(uint256 value) external onlyAdmins {
boosterPro.setIntervalLimit(value);
}
function setClaimOutFlow(address flow) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("setClaimOutFlow", flow));
_startAction(actionId);
_approveAction(actionId);
if (approvalCount == 2) {
boosterPro.setClaimOutFlow(flow);
_clearAction(actionId);
}
}
// transfer booster owner
function transferOwnership(address newOwner) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("transferOwnership", newOwner));
_startAction(actionId);
_approveAction(actionId);
if (approvalCount == 2) {
boosterPro.transferOwnership(newOwner);
_clearAction(actionId);
}
}
}
"
},
"contracts/interface/IBoosterPro.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
interface IBoosterPro {
function setActive(bool enable) external;
function setMaxBondsPerAddress(uint256 value) external;
function setPowers(uint256[3] calldata powers) external;
function setProportionEarn(bool isMin, uint256 value) external;
function setBoostingRate(bool isMin, uint256 value) external;
function setDisableUser(address user, bool disable) external;
function setIntervalLimit(uint256 value) external;
function setClaimOutFlow(address flow) external;
function emergencyWithdrawToken(address to, uint256 amount) external;
function emergencyWithdrawBonds(address to, uint256[] calldata tokenIds) external;
function transferOwnership(address newOwner) external;
}
"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 50
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [],
"evmVersion": "istanbul"
}
}}
Submitted on: 2025-11-07 13:03:53
Comments
Log in to comment.
No comments yet.