Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/MultiSigManager.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "./interface/IBarkHooks.sol";
contract MultiSigManager {
address public admin1;
address public admin2;
address public admin3;
address public robot;
IBarkHooks public barkHooks;
mapping(bytes32 => mapping(address => bool)) public approvals;
bytes32 public currentPendingAction;
event AdminChanged(address oldAdmin, address newAdmin, uint256 adminIndex);
event RobotChanged(address oldRobot, address newRobot);
event ActionApproved(bytes32 actionId, address indexed admin);
modifier onlyAdmins() {
require(
msg.sender == admin1 || msg.sender == admin2 || msg.sender == admin3,
"Not an admin"
);
_;
}
modifier onlyAdminOrRobot() {
require(
msg.sender == admin1 || msg.sender == admin2 || msg.sender == admin3 || msg.sender == robot,
"Not an admin or robot"
);
_;
}
constructor(address _admin1, address _admin2, address _admin3, address _robot, address _barkHooks) {
barkHooks = IBarkHooks(_barkHooks);
admin1 = _admin1;
admin2 = _admin2;
admin3 = _admin3;
robot = _robot;
}
function _clearPreviousPendingAction(bytes32 actionId) internal{
if (actionId != currentPendingAction && currentPendingAction != bytes32(0)) {
approvals[currentPendingAction][admin1] = false;
approvals[currentPendingAction][admin2] = false;
approvals[currentPendingAction][admin3] = false;
currentPendingAction = bytes32(0);
}
currentPendingAction = actionId;
}
function _resetPendingAction(bytes32 actionId) internal{
approvals[actionId][admin1] = false;
approvals[actionId][admin2] = false;
approvals[actionId][admin3] = false;
currentPendingAction = bytes32(0);
}
function changeAdmin(address newAdmin, uint256 adminIndex) external onlyAdmins {
require(adminIndex >= 1 && adminIndex <= 3, "Invalid admin index");
require(newAdmin != admin1 && newAdmin != admin2 && newAdmin != admin3, "Invalid newAdmin");
bytes32 actionId = keccak256(abi.encodePacked("changeAdmin", newAdmin, adminIndex));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 3) {
address[3] memory admins = [admin1, admin2, admin3];
address oldAdmin = admins[adminIndex - 1];
if (adminIndex == 1) admin1 = newAdmin;
else if (adminIndex == 2) admin2 = newAdmin;
else if (adminIndex == 3) admin3 = newAdmin;
_resetPendingAction(actionId);
emit AdminChanged(oldAdmin, newAdmin, adminIndex);
}
}
function changeRobot(address newRobot) external onlyAdmins {
require(robot != newRobot, "Invalid newRobot");
bytes32 actionId = keccak256(abi.encodePacked("changeRobot", newRobot));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 2) {
address oldRobot = robot;
robot = newRobot;
_resetPendingAction(actionId);
emit RobotChanged(oldRobot, newRobot);
}
}
function _getApprovalCount(bytes32 actionId) internal view returns (uint256 count) {
if (approvals[actionId][admin1]) count++;
if (approvals[actionId][admin2]) count++;
if (approvals[actionId][admin3]) count++;
return count;
}
function setClose() external onlyAdminOrRobot {
barkHooks.setClose();
}
function setFeeCalculator(address newCalculator) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("setFeeCalculator", newCalculator));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 2) {
barkHooks.setFeeCalculator(newCalculator);
_resetPendingAction(actionId);
}
}
function setCurveDisable(bool disable) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("setCurveDisable", disable));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 2) {
barkHooks.setCurveDisable(disable);
_resetPendingAction(actionId);
}
}
function setDonateDisable(bool disable) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("setDonateDisable", disable));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 2) {
barkHooks.setDonateDisable(disable);
_resetPendingAction(actionId);
}
}
function setTreasury(address newTreasury) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("setTreasury", newTreasury));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 2) {
barkHooks.setTreasury(newTreasury);
_resetPendingAction(actionId);
}
}
// transfer masterChef owner
function transferOwnership(address newOwner) external onlyAdmins {
bytes32 actionId = keccak256(abi.encodePacked("transferOwnership", newOwner));
_clearPreviousPendingAction(actionId);
approvals[actionId][msg.sender] = true;
emit ActionApproved(actionId, msg.sender);
if (_getApprovalCount(actionId) == 2) {
barkHooks.transferOwnership(newOwner);
_resetPendingAction(actionId);
}
}
}
"
},
"src/interface/IBarkHooks.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface IBarkHooks {
function setClose() external;
function setFeeCalculator(address newCalculator) external;
function setCurveDisable(bool disable) external;
function setDonateDisable(bool disbale) external;
function setTreasury(address newTreasury) external;
function transferOwnership(address newOwner) external;
}
"
}
},
"settings": {
"remappings": [
"@ensdomains/=lib/v4-core/node_modules/@ensdomains/",
"@openzeppelin/=lib/v4-core/lib/openzeppelin-contracts/",
"@uniswap/v4-core/=lib/v4-periphery/lib/v4-core/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-gas-snapshot/=lib/v4-periphery/lib/permit2/lib/forge-gas-snapshot/src/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"hardhat/=lib/v4-core/node_modules/hardhat/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"permit2/=lib/v4-periphery/lib/permit2/",
"solmate/=lib/solmate/src/",
"v4-core/=lib/v4-core/src/",
"v4-periphery/=lib/v4-periphery/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}
}}
Submitted on: 2025-10-13 11:26:56
Comments
Log in to comment.
No comments yet.