Skip to content

Commit

Permalink
Support multiple voucher signers
Browse files Browse the repository at this point in the history
  • Loading branch information
abarmat committed Jul 16, 2021
1 parent 772c460 commit 721e706
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
24 changes: 12 additions & 12 deletions contracts/statechannels/AllocationExchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ contract AllocationExchange is Governed {

IStaking private immutable staking;
IGraphToken private immutable graphToken;
address public authority;
mapping(address => bool) public authority;
mapping(address => bool) public allocationsRedeemed;

// -- Events

event AuthoritySet(address indexed account);
event AuthoritySet(address indexed account, bool authorized);
event AllocationRedeemed(address indexed allocationID, uint256 amount);
event TokensWithdrawn(address indexed to, uint256 amount);

Expand All @@ -58,7 +58,7 @@ contract AllocationExchange is Governed {

graphToken = _graphToken;
staking = _staking;
_setAuthority(_authority);
_setAuthority(_authority, true);
}

/**
Expand Down Expand Up @@ -86,19 +86,21 @@ contract AllocationExchange is Governed {
* @notice Set the authority allowed to sign vouchers.
* @dev Only the governor can set the authority
* @param _authority Address of the signing authority
* @param _authorized True if the authority is authorized to sign vouchers, false to unset
*/
function setAuthority(address _authority) external onlyGovernor {
_setAuthority(_authority);
function setAuthority(address _authority, bool _authorized) external onlyGovernor {
_setAuthority(_authority, _authorized);
}

/**
* @notice Set the authority allowed to sign vouchers.
* @param _authority Address of the signing authority
* @param _authorized True if the authority is authorized to sign vouchers, false to unset
*/
function _setAuthority(address _authority) private {
function _setAuthority(address _authority, bool _authorized) private {
require(_authority != address(0), "Exchange: empty authority");
authority = _authority;
emit AuthoritySet(authority);
authority[_authority] = _authorized;
emit AuthoritySet(_authority, _authorized);
}

/**
Expand Down Expand Up @@ -138,10 +140,8 @@ contract AllocationExchange is Governed {

// Signature check
bytes32 messageHash = keccak256(abi.encodePacked(_voucher.allocationID, _voucher.amount));
require(
authority == ECDSA.recover(messageHash, _voucher.signature),
"Exchange: invalid signer"
);
address voucherSigner = ECDSA.recover(messageHash, _voucher.signature);
require(authority[voucherSigner], "Exchange: invalid signer");

// Mark allocation as collected
allocationsRedeemed[_voucher.allocationID] = true;
Expand Down
20 changes: 13 additions & 7 deletions test/payments/allocationExchange.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('AllocationExchange', () => {

// Ensure the exchange is correctly setup
await staking.connect(governor.signer).setAssetHolder(allocationExchange.address, true)
await allocationExchange.connect(governor.signer).setAuthority(authority.address)
await allocationExchange.connect(governor.signer).setAuthority(authority.address, true)
await allocationExchange.approveAll()
})

Expand Down Expand Up @@ -114,21 +114,27 @@ describe('AllocationExchange', () => {

describe('config', function () {
it('should set an authority', async function () {
// Set authority
const newAuthority = randomAddress()
const tx = allocationExchange.connect(governor.signer).setAuthority(newAuthority)
await expect(tx).emit(allocationExchange, 'AuthoritySet').withArgs(newAuthority)
expect(await allocationExchange.authority()).eq(newAuthority)
const tx1 = allocationExchange.connect(governor.signer).setAuthority(newAuthority, true)
await expect(tx1).emit(allocationExchange, 'AuthoritySet').withArgs(newAuthority, true)
expect(await allocationExchange.authority(newAuthority)).eq(true)

// Unset authority
const tx2 = allocationExchange.connect(governor.signer).setAuthority(newAuthority, false)
await expect(tx2).emit(allocationExchange, 'AuthoritySet').withArgs(newAuthority, false)
expect(await allocationExchange.authority(newAuthority)).eq(false)
})

it('reject set an authority if not allowed', async function () {
const newAuthority = randomAddress()
const tx = allocationExchange.connect(indexer.signer).setAuthority(newAuthority)
const tx = allocationExchange.connect(indexer.signer).setAuthority(newAuthority, true)
await expect(tx).revertedWith(' Only Governor can call')
})

it('reject set an empty authority', async function () {
const newAuthority = AddressZero
const tx = allocationExchange.connect(governor.signer).setAuthority(newAuthority)
const tx = allocationExchange.connect(governor.signer).setAuthority(newAuthority, true)
await expect(tx).revertedWith('Exchange: empty authority')
})

Expand Down Expand Up @@ -225,7 +231,7 @@ describe('AllocationExchange', () => {
const allocationID = '0xfefefefefefefefefefefefefefefefefefefefe'

// Ensure the exchange is correctly setup
await allocationExchange.connect(governor.signer).setAuthority(authority.address)
await allocationExchange.connect(governor.signer).setAuthority(authority.address, true)
await allocationExchange.approveAll()

// Initiate a withdrawal
Expand Down

0 comments on commit 721e706

Please sign in to comment.