// guard.sol -- simple whitelist implementation of DSAuthority
// Copyright (C) 2017 DappHub, LLC
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity 0.5.12;
contract DSAuthority {
function canCall(
address src,
address dst,
bytes4 sig
) public view returns (bool);
}
contract DSAuthEvents {
event LogSetAuthority(address indexed authority);
event LogSetOwner(address indexed owner);
event OwnerUpdate(address indexed owner, address indexed newOwner);
}
contract DSAuth is DSAuthEvents {
DSAuthority public authority;
address public owner;
address public newOwner;
constructor() public {
owner = msg.sender;
emit LogSetOwner(msg.sender);
}
// Warning: you should absolutely sure you want to give up authority!!!
function disableOwnership() public onlyOwner {
owner = address(0);
emit OwnerUpdate(msg.sender, owner);
}
function transferOwnership(address newOwner_) public onlyOwner {
require(newOwner_ != owner, "TransferOwnership: the same owner.");
newOwner = newOwner_;
}
function acceptOwnership() public {
require(
msg.sender == newOwner,
"AcceptOwnership: only new owner do this."
);
emit OwnerUpdate(owner, newOwner);
owner = newOwner;
newOwner = address(0x0);
}
///[snow] guard is Authority who inherit DSAuth.
function setAuthority(DSAuthority authority_) public onlyOwner {
authority = authority_;
emit LogSetAuthority(address(authority));
}
modifier onlyOwner {
require(isOwner(msg.sender), "ds-auth-non-owner");
_;
}
function isOwner(address src) internal view returns (bool) {
return bool(src == owner);
}
modifier auth {
require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
_;
}
function isAuthorized(address src, bytes4 sig)
internal
view
returns (bool)
{
if (src == address(this)) {
return true;
} else if (src == owner) {
return true;
} else if (authority == DSAuthority(0)) {
return false;
} else {
return authority.canCall(src, address(this), sig);
}
}
}
contract DSGuardEvents {
event LogPermit(
bytes32 indexed src,
bytes32 indexed dst,
bytes32 indexed sig
);
event LogForbid(
bytes32 indexed src,
bytes32 indexed dst,
bytes32 indexed sig
);
}
contract DSGuard is DSAuth, DSAuthority, DSGuardEvents {
bytes32 public constant ANY = bytes32(uint256(-1));
mapping(bytes32 => mapping(bytes32 => mapping(bytes32 => bool))) acl;
function canCall(
address src_,
address dst_,
bytes4 sig
) public view returns (bool) {
bytes32 src = bytes32(bytes20(src_));
bytes32 dst = bytes32(bytes20(dst_));
return
acl[src][dst][sig] ||
acl[src][dst][ANY] ||
acl[src][ANY][sig] ||
acl[src][ANY][ANY] ||
acl[ANY][dst][sig] ||
acl[ANY][dst][ANY] ||
acl[ANY][ANY][sig] ||
acl[ANY][ANY][ANY];
}
function permit(
bytes32 src,
bytes32 dst,
bytes32 sig
) public auth {
acl[src][dst][sig] = true;
emit LogPermit(src, dst, sig);
}
function forbid(
bytes32 src,
bytes32 dst,
bytes32 sig
) public auth {
acl[src][dst][sig] = false;
emit LogForbid(src, dst, sig);
}
function permit(
address src,
address dst,
bytes32 sig
) public auth {
permit(bytes32(bytes20(src)), bytes32(bytes20(dst)), sig);
}
function permitx(address src, address dst) public auth {
permit(bytes32(bytes20(src)), bytes32(bytes20(dst)), ANY);
}
function forbid(
address src,
address dst,
bytes32 sig
) public auth {
forbid(bytes32(bytes20(src)), bytes32(bytes20(dst)), sig);
}
function forbidx(address src, address dst) public auth {
forbid(bytes32(bytes20(src)), bytes32(bytes20(dst)), ANY);
}
}
{
"compilationTarget": {
"DSGuard.sol": "DSGuard"
},
"evmVersion": "petersburg",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"src","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"dst","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"sig","type":"bytes32"}],"name":"LogForbid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"src","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"dst","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"sig","type":"bytes32"}],"name":"LogPermit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"},{"constant":true,"inputs":[],"name":"ANY","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"internalType":"contract DSAuthority","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"src_","type":"address"},{"internalType":"address","name":"dst_","type":"address"},{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"canCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"disableOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"bytes32","name":"sig","type":"bytes32"}],"name":"forbid","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"src","type":"bytes32"},{"internalType":"bytes32","name":"dst","type":"bytes32"},{"internalType":"bytes32","name":"sig","type":"bytes32"}],"name":"forbid","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"forbidx","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"bytes32","name":"sig","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"src","type":"bytes32"},{"internalType":"bytes32","name":"dst","type":"bytes32"},{"internalType":"bytes32","name":"sig","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"permitx","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract DSAuthority","name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]