diff --git a/src/Blue.sol b/src/Blue.sol index 50dee219d..3be894499 100644 --- a/src/Blue.sol +++ b/src/Blue.sol @@ -35,6 +35,8 @@ contract Blue { // Storage. + // Owner. + address public owner; // User' supply balances. mapping(Id => mapping(address => uint)) public supplyShare; // User' borrow balances. @@ -52,6 +54,25 @@ contract Blue { // Interests last update (used to check if a market has been created). mapping(Id => uint) public lastUpdate; + // Constructor. + + constructor(address newOwner) { + owner = newOwner; + } + + // Modifiers. + + modifier onlyOwner() { + require(msg.sender == owner, "not owner"); + _; + } + + // Only owner functions. + + function transferOwnership(address newOwner) external onlyOwner { + owner = newOwner; + } + // Markets management. function createMarket(Market calldata market) external { diff --git a/test/forge/Blue.t.sol b/test/forge/Blue.t.sol index d814c7f97..e31bbd849 100644 --- a/test/forge/Blue.t.sol +++ b/test/forge/Blue.t.sol @@ -28,7 +28,7 @@ contract BlueTest is Test { function setUp() public { // Create Blue. - blue = new Blue(); + blue = new Blue(msg.sender); // List a market. borrowableAsset = new ERC20("borrowable", "B", 18); @@ -91,6 +91,30 @@ contract BlueTest is Test { // Tests + function testOwner(address owner) public { + Blue blue2 = new Blue(owner); + + assertEq(blue2.owner(), owner, "owner"); + } + + function testTransferOwnership(address oldOwner, address newOwner) public { + Blue blue2 = new Blue(oldOwner); + + vm.prank(oldOwner); + blue2.transferOwnership(newOwner); + assertEq(blue2.owner(), newOwner, "owner"); + } + + function testTransferOwnershipWhenNotOwner(address attacker, address newOwner) public { + vm.assume(attacker != address(0xdead)); + + Blue blue2 = new Blue(address(0xdead)); + + vm.prank(attacker); + vm.expectRevert("not owner"); + blue2.transferOwnership(newOwner); + } + function testSupply(uint amount) public { amount = bound(amount, 1, 2 ** 64);