diff --git a/contracts/optimism/connectors/authority/events.sol b/contracts/optimism/connectors/authority/events.sol new file mode 100644 index 00000000..3d273d2a --- /dev/null +++ b/contracts/optimism/connectors/authority/events.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogAddAuth(address indexed _msgSender, address indexed _authority); + event LogRemoveAuth(address indexed _msgSender, address indexed _authority); +} \ No newline at end of file diff --git a/contracts/optimism/connectors/authority/helpers.sol b/contracts/optimism/connectors/authority/helpers.sol new file mode 100644 index 00000000..7e65a77e --- /dev/null +++ b/contracts/optimism/connectors/authority/helpers.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import { DSMath } from "../../common/math.sol"; +import { Basic } from "../../common/basic.sol"; +import { ListInterface } from "./interface.sol"; + +abstract contract Helpers is DSMath, Basic { + ListInterface internal constant listContract = ListInterface(0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687); + + function checkAuthCount() internal view returns (uint count) { + uint64 accountId = listContract.accountID(address(this)); + count = listContract.accountLink(accountId).count; + } +} diff --git a/contracts/optimism/connectors/authority/interface.sol b/contracts/optimism/connectors/authority/interface.sol new file mode 100644 index 00000000..b0d73b29 --- /dev/null +++ b/contracts/optimism/connectors/authority/interface.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +interface ListInterface { + struct AccountLink { + address first; + address last; + uint64 count; + } + + function accountID(address) external view returns (uint64); + function accountLink(uint64) external view returns (AccountLink memory); +} \ No newline at end of file diff --git a/contracts/optimism/connectors/authority/main.sol b/contracts/optimism/connectors/authority/main.sol new file mode 100644 index 00000000..29d58c09 --- /dev/null +++ b/contracts/optimism/connectors/authority/main.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +/** + * @title Authority. + * @dev Manage Authorities to DSA. + */ + +import { AccountInterface } from "../../common/interfaces.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; + +abstract contract AuthorityResolver is Events, Helpers { + /** + * @dev Add New authority + * @notice Add an address as account authority + * @param authority The authority Address. + */ + function add( + address authority + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + require(authority != address(0), "Not-valid-authority"); + AccountInterface _dsa = AccountInterface(address(this)); + if (_dsa.isAuth(authority)) { + authority = address(0); + } else { + _dsa.enable(authority); + } + + _eventName = "LogAddAuth(address,address)"; + _eventParam = abi.encode(msg.sender, authority); + } + + /** + * @dev Remove authority + * @notice Remove an address as account authority + * @param authority The authority Address. + */ + function remove( + address authority + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + require(checkAuthCount() > 1, "Removing-all-authorities"); + require(authority != address(0), "Not-valid-authority"); + AccountInterface _dsa = AccountInterface(address(this)); + if (_dsa.isAuth(authority)) { + _dsa.disable(authority); + } else { + authority = address(0); + } + + _eventName = "LogRemoveAuth(address,address)"; + _eventParam = abi.encode(msg.sender, authority); + } +} + +contract ConnectV2AuthOptimism is AuthorityResolver { + string public constant name = "Auth-v1.1"; +}