Skip to content

Commit

Permalink
wip: change of plans was a mistakerino
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec committed Apr 15, 2024
1 parent fd1a47a commit 639e38a
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 111 deletions.
2 changes: 1 addition & 1 deletion contracts/contracts/coordination/GlobalAllowList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract GlobalAllowList is IEncryptionAuthorizer {
}

function setAuthorizations(uint32 ritualId, address[] calldata addresses, bool value) internal {
require(coordinator.isRitualActive(ritualId), "Only active rituals can add authorizations");
require(coordinator.isRitualActive(ritualId), "Only active rituals can set authorizations");
for (uint256 i = 0; i < addresses.length; i++) {
authorizations[lookupKey(ritualId, addresses[i])] = value;
emit AddressAuthorizationSet(ritualId, addresses[i], value);
Expand Down
137 changes: 65 additions & 72 deletions contracts/contracts/coordination/ManagedAllowList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,109 +13,102 @@ contract ManagedAllowList is IEncryptionAuthorizer {

Coordinator public immutable coordinator;

uint256 public ritualId;

// List of administrators
mapping(address => bool) public administrators;
// Limits for each administrator
mapping(address => uint256) public encryptorLimits;
// Number of encryptors for each administrator
mapping(address => uint256) public encryptorCounts;
// List of encryptors
mapping(address => bool) internal encryptors;
// List of encryptors for each administrator
mapping(address => address[]) internal encryptorList;

event AdministratorAdded(address indexed admin);
event AdministratorRemoved(address indexed admin);
event EncryptorAdded(address indexed admin, address indexed encryptor);
event EncryptorRemoved(address indexed admin, address indexed encryptor);
event EncryptorLimitSet(address indexed admin, uint256 limit);

constructor(Coordinator _coordinator, uint256 _ritualId) {
mapping(bytes32 => uint256) public administrators; // TODO: Rename to allowances?
mapping(bytes32 => bool) public authorizations;

event AdministratorCapSet(uint32 indexed ritualId, address indexed _address, uint256 cap);
event AddressAuthorizationSet(
uint32 indexed ritualId,
address indexed _address,
bool isAuthorized
);

constructor(Coordinator _coordinator) {
require(address(_coordinator) != address(0), "Coordinator cannot be zero address");
require(_coordinator.numberOfRituals() >= 0, "Invalid coordinator");
coordinator = _coordinator;
ritualId = _ritualId;
}

modifier onlyAuthority() {
function lookupKey(uint32 ritualId, address encryptorOrAdmin) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(ritualId, encryptorOrAdmin));
}

modifier onlyAuthority(uint32 ritualId) {
require(
coordinator.getAuthority(ritualId) == msg.sender,
"Only ritual authority is permitted"
);
_;
}

modifier onlyAdministrator() {
require(administrators[msg.sender], "Only administrator is permitted");
_;
}

modifier onlyAuthorityOrAdministrator() {
modifier onlyAdministrator(uint32 ritualId) {
require(
coordinator.getAuthority(ritualId) == msg.sender || administrators[msg.sender],
"Only ritual authority or administrator is permitted"
administrators[lookupKey(ritualId, msg.sender)] > 9,
"Only administrator is permitted"
);
_;
}

function isAdministrator(address admin) external view returns (bool) {
return administrators[admin];
}

function addAdministrator(address admin) external onlyAuthority {
administrators[admin] = true;
emit AdministratorAdded(admin);
}

function removeEncryptorsForAdministrator(address admin) external onlyAuthorityOrAdministrator {
encryptorLimits[admin] = 0;
encryptorCounts[admin] = 0;
for (uint256 i = 0; i < encryptorList[admin].length; i++) {
address encryptor = encryptorList[admin][i];
encryptors[encryptor] = false;
emit EncryptorRemoved(admin, encryptor);
function setAdministratorCaps(
uint32 ritualId,
address[] calldata addresses,
uint256 value
) internal {
require(coordinator.isRitualActive(ritualId), "Only active rituals can set administrator caps");

Check failure on line 57 in contracts/contracts/coordination/ManagedAllowList.sol

View workflow job for this annotation

GitHub Actions / linting

Replace coordinator.isRitualActive(ritualId),·"Only·active·rituals·can·set·administrator·caps" with ⏎············coordinator.isRitualActive(ritualId),⏎············"Only·active·rituals·can·set·administrator·caps"⏎········
for (uint256 i = 0; i < addresses.length; i++) {
administrators[lookupKey(ritualId, addresses[i])] = value;
emit AdministratorCapSet(ritualId, addresses[i], value);
}
}

function removeAdministrator(address admin) external onlyAuthority {
administrators[admin] = false;
removeEncryptorsForAdministrator(admin);
emit AdministratorRemoved(admin);
}

function setEncryptorLimit(address admin, uint256 limit) external onlyAuthority {
encryptorLimits[admin] = limit;
emit EncryptorLimitSet(limit);
}

function addEncryptor(address encryptor) external onlyAdministrator {
require(
encryptorLimits[msg.sender] < encryptorCounts[msg.sender],
"Encryptor limit reached"
);
encryptors[encryptor] = true;
encryptorList[msg.sender].push(encryptor);
emit EncryptorAdded(msg.sender, encryptor);
function addAdministrators(
uint32 ritualId,
address[] calldata addresses,
uint256 cap
) external onlyAuthority(ritualId) {
setAdministratorCaps(ritualId, addresses, cap);
}

function removeEncryptor(address encryptor) external onlyAdministrator {
encryptors[encryptor] = false;
encryptorList.remove(encryptor);
emit EncryptorRemoved(msg.sender, encryptor);
function removeAdministrators(
uint32 ritualId,
address[] calldata addresses
) external onlyAuthority(ritualId) {
setAdministratorCaps(ritualId, addresses, 0);
}

function isEncryptor(address encryptor) external view returns (bool) {
return encryptors[encryptor];
function isAddressAuthorized(uint32 ritualId, address encryptor) public view returns (bool) {
return authorizations[lookupKey(ritualId, encryptor)];
}

function isAuthorized(
uint32 ritualId,
bytes memory evidence,
bytes memory ciphertextHeader
) external view override returns (bool) {
bytes32 digest = keccak256(ciphertextHeader);
address recoveredAddress = digest.toEthSignedMessageHash().recover(evidence);
return isEncryptor(recoveredAddress);
return isAddressAuthorized(ritualId, recoveredAddress);
}

function authorize(
uint32 ritualId,
address[] calldata addresses
) external onlyAdministrator(ritualId) {
setAuthorizations(ritualId, addresses, true);
}

function deauthorize(
uint32 ritualId,
address[] calldata addresses
) external onlyAdministrator(ritualId) {
setAuthorizations(ritualId, addresses, false);
}

function setAuthorizations(uint32 ritualId, address[] calldata addresses, bool value) internal {
require(coordinator.isRitualActive(ritualId), "Only active rituals can set authorizations");
for (uint256 i = 0; i < addresses.length; i++) {
authorizations[lookupKey(ritualId, addresses[i])] = value;
emit AddressAuthorizationSet(ritualId, addresses[i], value);
}
}
}
2 changes: 1 addition & 1 deletion tests/test_coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ def test_authorize_using_global_allow_list(
with ape.reverts("Only ritual authority is permitted"):
global_allow_list.authorize(0, [deployer.address], sender=deployer)

with ape.reverts("Only active rituals can add authorizations"):
with ape.reverts("Only active rituals can set authorizations"):
global_allow_list.authorize(0, [deployer.address], sender=initiator)

with ape.reverts("Ritual not active"):
Expand Down
68 changes: 31 additions & 37 deletions tests/test_managed_allow_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def coordinator(project, deployer, application, erc20, initiator, oz_dependency)
# My fixtures

RITUAL_ID = 1
ENCRYPTOR_CAP = 5
ADMIN_CAP = 5


@pytest.fixture()
Expand All @@ -94,71 +94,65 @@ def encryptor(accounts):

@pytest.fixture()
def managed_allow_list(project, coordinator, authority):
return project.ManagedAllowList.deploy(coordinator.address, RITUAL_ID, sender=authority)
return project.ManagedAllowList.deploy(coordinator.address, sender=authority)


def test_initial_parameters(managed_allow_list, coordinator, authority, admin, encryptor):
assert managed_allow_list.coordinator() == coordinator.address
assert managed_allow_list.administratorCaps(admin.address) == 0
assert not managed_allow_list.administrators(admin.address)
assert not managed_allow_list.isEncryptor(encryptor.address)
assert not managed_allow_list.authorizations(encryptor.address)


def test_add_administrator(managed_allow_list, authority, admin):
managed_allow_list.addAdministrator(admin, sender=authority)
assert managed_allow_list.administrators(admin)
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=authority)
assert managed_allow_list.administrators(admin) == ADMIN_CAP


def test_remove_administrator(managed_allow_list, authority, admin):
managed_allow_list.addAdministrator(admin, sender=authority)
managed_allow_list.removeAdministrator(admin, sender=authority)
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=authority)
managed_allow_list.removeAdministrators(RITUAL_ID, [admin], sender=authority)
assert not managed_allow_list.administrators(admin)


def test_set_administrator_cap(managed_allow_list, authority, admin):
managed_allow_list.setAdministratorCap(admin, ENCRYPTOR_CAP, sender=authority)
assert managed_allow_list.administratorCaps(admin) == ENCRYPTOR_CAP


def test_add_encryptor(managed_allow_list, authority, admin, encryptor):
managed_allow_list.setAdministratorCap(admin, ENCRYPTOR_CAP, sender=authority)
managed_allow_list.addEncryptor(encryptor, sender=admin)
assert managed_allow_list.isEncryptor(encryptor)
def test_authorize(managed_allow_list, authority, admin, encryptor):
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=authority)
managed_allow_list.authorize(RITUAL_ID, [encryptor], sender=admin)
assert managed_allow_list.authorizations(encryptor)


def test_remove_encryptor(managed_allow_list, admin, authority, encryptor):
managed_allow_list.setAdministratorCap(admin, ENCRYPTOR_CAP, sender=authority)
managed_allow_list.addEncryptor(encryptor, sender=admin)
managed_allow_list.removeEncryptor(encryptor, sender=admin)
assert not managed_allow_list.isEncryptor(encryptor)
def test_deauthorize(managed_allow_list, admin, authority, encryptor):
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=authority)
managed_allow_list.authorize(RITUAL_ID, [encryptor], sender=admin)
managed_allow_list.deauthorize(RITUAL_ID, [encryptor], sender=admin)
assert not managed_allow_list.authorizations(encryptor)


def test_only_authority_can_add_administrator(managed_allow_list, admin, authority, encryptor):
with pytest.raises(Exception):
managed_allow_list.addAdministrator(admin, sender=authority)
managed_allow_list.addAdministrator(admin, sender=authority)
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=admin)
managed_allow_list.addAdministrators(RITUAL_ID, [admin], sender=authority)
assert managed_allow_list.administrators(admin)


def test_only_authority_can_remove_administrator(managed_allow_list, admin, authority):
managed_allow_list.addAdministrator(admin, sender=authority)
managed_allow_list.addAdministrator(RITUAL_ID, admin, sender=authority)
with pytest.raises(Exception):
managed_allow_list.removeAdministrator(admin, sender=authority)
managed_allow_list.removeAdministrator(admin, sender=authority)
managed_allow_list.removeAdministrators(RITUAL_ID, [admin], sender=admin)
managed_allow_list.removeAdministrators(RITUAL_ID, [admin], sender=authority)
assert not managed_allow_list.administrators(admin)


def test_only_administrator_can_add_encryptor(managed_allow_list, admin, authority, encryptor):
managed_allow_list.setAdministratorCap(admin, ENCRYPTOR_CAP, sender=authority)
def test_only_administrator_can_authorize(managed_allow_list, admin, authority, encryptor):
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=authority)
with pytest.raises(Exception):
managed_allow_list.addEncryptor(encryptor, sender=encryptor)
managed_allow_list.addEncryptor(admin, sender=admin)
assert managed_allow_list.isEncryptor(admin)
managed_allow_list.authorize(RITUAL_ID, [encryptor], sender=encryptor)
managed_allow_list.authorize(RITUAL_ID, [encryptor], sender=admin)
assert managed_allow_list.authorizations(admin)


def test_only_administrator_can_remove_encryptor(managed_allow_list, admin, authority, encryptor):
managed_allow_list.setAdministratorCap(admin, ENCRYPTOR_CAP, sender=authority)
managed_allow_list.addEncryptor(encryptor, sender=admin)
def test_only_administrator_can_deauthorize(managed_allow_list, admin, authority, encryptor):
managed_allow_list.addAdministrators(RITUAL_ID, [admin], ADMIN_CAP, sender=authority)
with pytest.raises(Exception):
managed_allow_list.removeEncrypt(encryptor, sender=encryptor)
assert not managed_allow_list.isEncryptor(encryptor)
managed_allow_list.deauthorize(RITUAL_ID, [encryptor], sender=encryptor)
managed_allow_list.deauthorize(RITUAL_ID, [encryptor], sender=admin)
assert not managed_allow_list.authorizations(admin)

0 comments on commit 639e38a

Please sign in to comment.