MultiOwnable
0xd5bc09d5…bd7720Source details
| Property | Value |
|---|---|
| Keccak256 Hash | 0xd5bc09d51ea952718d51fc0c347aad20278f6a1c7a0fda63e40ea9317fbd7720 |
| Source URL | https://raw.githubusercontent.com/busytoby/atropa_pulsechain/58607494f7741b80525953e4a85bc99e66fd20fc/solidity/dysnomia/lib/multiownable.sol |
| Source Revision | 58607494f7741b80525953e4a85bc99e66fd20fc |
| Source Status | Canonical source snapshot; deployed bytecode equivalence is only established where a deployment record says so. |
| Compiler | solc 0.8.21; optimizer enabled with 200 runs |
| Compiler Configuration | {"evmVersion":"compiler-default","optimizer":{"enabled":true,"runs":200},"version":"0.8.21+commit.d9974bed.Linux.g++"} |
| Compilation Closure Hash | 0x6c094bbab1cc9c0e942bb850c4564398cdd185bc10d7c1058d515c47603e2725 |
| Compilation Closure Files | 1 |
| Hash Generated | 2026-09-14T19:34:21Z |
Overview
Section titled “Overview”MultiOwnable is an abstract contract providing multi-owner access control. Unlike OpenZeppelin’s Ownable which has a single owner, MultiOwnable allows multiple addresses to have owner privileges simultaneously.
- Kind: Abstract Contract
- License: Sharia
- Solidity: ^0.8.21
- Source:
lib/multiownable.sol
Inheritance Chain (C3 Linearized)
Section titled “Inheritance Chain (C3 Linearized)”No base contracts; this contract has no parents.
Immediate Parents
Section titled “Immediate Parents”None (root of its hierarchy).
What This Means For Players
Section titled “What This Means For Players”Plain English Summary: MultiOwnable allows shared control - it lets multiple people manage the same thing. Instead of having just one admin, a contract can have many admins who all have equal power. This is essential for the Dysnomia ecosystem where game contracts need to interact with each other.
Real-World Analogy: Think of a shared bank account that has multiple signatories. Any of the signatories can make transactions - you don’t need everyone to approve. MultiOwnable works the same way: if you’re on the list of owners, you can control the contract.
How It Affects Your Gameplay:
- Shared access - Your LAU, SHIO, and other tokens may have multiple owners (you + game contracts)
- Chain of trust - Game contracts add each other as owners to enable coordination
- Revocable - Owners can be added or removed by existing owners
State Variables
Section titled “State Variables”| Variable | Type | Visibility | Mutability | Initial Value | NatSpec |
|---|---|---|---|---|---|
_owners |
mapping(address => bool) |
private | mutable | `` |
Modifiers
Section titled “Modifiers”| Modifier | Parameters | NatSpec |
|---|---|---|
onlyOwners |
(none) |
Events
Section titled “Events”| Event | Parameters | Anonymous | NatSpec |
|---|---|---|---|
OwnershipUpdate |
address indexed newOwner, bool indexed state | no |
Errors
Section titled “Errors”| Error | Parameters | NatSpec |
|---|---|---|
OwnableUnauthorizedAccount |
address origin, address account, address what | |
OwnableInvalidOwner |
address origin, address owner, address what |
Constructor
Section titled “Constructor”constructor
Section titled “constructor”constructorconstructor
constructor(address initialOwner)- Parameters: address initialOwner
Functions
Section titled “Functions”External & Public
Section titled “External & Public”ownerfunction
function owner() external view virtual returns (address)A callable deployment has not been resolved for this reference.
- Visibility: external
- State Mutability: view
- Virtual: yes
- Returns: address
ownerfunction
function owner(address cOwner) public view virtual returns (bool)A callable deployment has not been resolved for this reference.
- Visibility: public
- State Mutability: view
- Virtual: yes
- Parameters: address cOwner
- Returns: bool
renounceOwnership
Section titled “renounceOwnership”renounceOwnershipfunction
function renounceOwnership(address toRemove) public virtual onlyOwnersA callable deployment has not been resolved for this reference.
- Visibility: public
- Virtual: yes
- Modifiers:
onlyOwners - Parameters: address toRemove
addOwner
Section titled “addOwner”addOwnerfunction
function addOwner(address newOwner) public virtual onlyOwnersA callable deployment has not been resolved for this reference.
- Visibility: public
- Virtual: yes
- Modifiers:
onlyOwners - Parameters: address newOwner
Internal
Section titled “Internal”_checkOwner
Section titled “_checkOwner”_checkOwnerfunction
function _checkOwner() internal view virtual- Visibility: internal
- State Mutability: view
- Virtual: yes
_changeOwnership
Section titled “_changeOwnership”_changeOwnershipfunction
function _changeOwnership(address cOwner, bool cState) internal virtual- Visibility: internal
- Virtual: yes
- Parameters: address cOwner, bool cState
Modifier
Section titled “Modifier”onlyOwners
Section titled “onlyOwners”modifier onlyOwners() { _checkOwner(); _;}- Description: Restricts function access to owners only
- Checks: Both msg.sender AND tx.origin - allows if either is an owner
Contract Interactions
Section titled “Contract Interactions”Depended On By
Section titled “Depended On By”- DYSNOMIA - All tokens inherit this
- Every contract in the ecosystem
Special Mechanisms
Section titled “Special Mechanisms”Dual Sender Check
Section titled “Dual Sender Check”The _checkOwner function checks both:
if (!owner(msg.sender) && !owner(tx.origin)) { revert OwnableUnauthorizedAccount(...);}This allows:
- Direct calls from owner addresses
- Calls through contracts where tx.origin is an owner
- Factory patterns where the deploying contract is trusted
Initial Owner
Section titled “Initial Owner”Constructor requires a non-zero initial owner:
constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(...); } _changeOwnership(initialOwner, true);}No Enumeration
Section titled “No Enumeration”Owners cannot be enumerated through a getter. owner(address) checks one candidate, while owner() returns the contract address. Reconstruct the set from OwnershipUpdate events when a complete owner list is needed.
Usage Pattern
Section titled “Usage Pattern”contract MyContract is MultiOwnable { constructor() MultiOwnable(msg.sender) {}
function adminFunction() public onlyOwners { // Only owners can call this }
function addAdmin(address newAdmin) public onlyOwners { addOwner(newAdmin); }}Security Considerations
Section titled “Security Considerations”- Any owner can add new owners
- Any owner can remove any owner (including themselves)
- No protection against removing all owners
- tx.origin check enables some use cases but has known security implications
- Consider carefully before using in high-security contexts
Compiled ABI
Section titled “Compiled ABI”The compiled ABI below is produced by solc 0.8.21 from the exact source bytes recorded in Source details. Consumers can paste it directly into ethers/web3/viem.
Click to expand JSON ABI
[ { "inputs": [ { "internalType": "address", "name": "origin", "type": "address" }, { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "what", "type": "address" } ], "name": "OwnableInvalidOwner", "type": "error" }, { "inputs": [ { "internalType": "address", "name": "origin", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "what", "type": "address" } ], "name": "OwnableUnauthorizedAccount", "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }, { "indexed": true, "internalType": "bool", "name": "state", "type": "bool" } ], "name": "OwnershipUpdate", "type": "event" }, { "inputs": [ { "internalType": "address", "name": "newOwner", "type": "address" } ], "name": "addOwner", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "cOwner", "type": "address" } ], "name": "owner", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "toRemove", "type": "address" } ], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]