Skip to content
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time
/// FsmGovernanceInterface -- governance interface for oracle security modules
// Copyright (C) 2019 Maker Ecosystem Growth Holdings, INC.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <>.
pragma solidity 0.6.7;
abstract contract FsmLike {
function stop() virtual external;
abstract contract AuthorityLike {
function canCall(address src, address dst, bytes4 sig) virtual public view returns (bool);
contract FsmGovernanceInterface {
// --- Authorization ---
// The owner of the FSM interface
address public owner;
// Modifier that checks if the msg.sender is the owner
modifier onlyOwner { require(msg.sender == owner, "fsm-governance-interface/only-owner"); _;}
// The FSM interface authority
address public authority;
// Checks if msg.sender is allowed to call a specific function
modifier isAuthorized {
require(canCall(msg.sender, msg.sig), "fsm-governance-interface/not-authorized");
* @notice View function that checks whether an address is allowed to call a function
* @param src The address for which we check permissions
* @param sig The signature of the function to check permissions for
function canCall(address src, bytes4 sig) internal view returns (bool) {
if (src == address(this)) {
return true;
} else if (src == owner) {
return true;
} else if (authority == address(0)) {
return false;
} else {
return AuthorityLike(authority).canCall(src, address(this), sig);
// --- Variables ---
// Mapping of collateral types and associated FSMs
mapping (bytes32 => address) public fsms;
// --- Events ---
event SetFsm(bytes32 collateralType, address fsm);
event SetOwner(address owner);
event SetAuthority(address authority);
event StopFsm(bytes32 collateralType);
constructor() public {
owner = msg.sender;
emit SetOwner(owner);
// --- Core Logic ---
* @notice Whitelist a new FSM for a specific collateral type
* @param collateralType The collateral type for which we set a FSM
* @param fsm The FSM address to associate with the collateral type
function setFsm(bytes32 collateralType, address fsm) external onlyOwner {
fsms[collateralType] = fsm;
emit SetFsm(collateralType, fsm);
* @notice Set a new owner in the contract
* @param owner_ New owner to set
function setOwner(address owner_) external onlyOwner {
owner = owner_;
emit SetOwner(owner);
* @notice Set a new authority in the contract
* @notice authority_ New authority address
function setAuthority(address authority_) external onlyOwner {
authority = authority_;
emit SetAuthority(authority);
* @notice Stop a whitelisted FSM
* @param collateralType Collateral type whose FSM will be stopped
function stopFsm(bytes32 collateralType) external isAuthorized {
emit StopFsm(collateralType);