Skip to content

Commit 85b0291

Browse files
authored
staking: refactor address from pub key function and add test for uncompressed key (#225)
1 parent 09f0545 commit 85b0291

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

contracts/Staking.sol

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -633,20 +633,30 @@ contract Staking is Governed {
633633

634634
// Only allocations with a token amount are allowed
635635
require(_tokens > 0, "Allocation: cannot allocate zero tokens");
636+
636637
// Need to have tokens in our stake to be able to allocate
637638
require(indexerStake.hasTokens(), "Allocation: indexer has no stakes");
639+
638640
// Need to have free capacity not used for other purposes to allocate
639641
require(
640642
getIndexerCapacity(indexer) >= _tokens,
641643
"Allocation: not enough tokens available to allocate"
642644
);
645+
643646
// Can only allocate tokens to a SubgraphDeployment if not currently allocated
644647
require(
645648
indexerStake.hasAllocation(_subgraphDeploymentID) == false,
646649
"Allocation: cannot allocate if already allocated"
647650
);
651+
652+
// Channel public key must be in uncompressed format
653+
require(
654+
uint8(_channelPubKey[0]) == 4 && _channelPubKey.length == 65,
655+
"Allocation: invalid channel public key"
656+
);
657+
648658
// Cannot reuse a channelID that has been used in the past
649-
address channelID = publicKeyToAddress(bytes(_channelPubKey[1:])); // solium-disable-line
659+
address channelID = address(uint256(keccak256(bytes(_channelPubKey[1:])))); // solium-disable-line
650660
require(isChannel(channelID) == false, "Allocation: channel ID already in use");
651661

652662
// Allocate and setup channel
@@ -969,15 +979,4 @@ contract Staking is Governed {
969979
}
970980
return id;
971981
}
972-
973-
/**
974-
* @dev Convert an uncompressed public key to an Ethereum address
975-
* @param _publicKey Public key in uncompressed format without the 1 byte prefix
976-
* @return An Ethereum address corresponding to the public key
977-
*/
978-
function publicKeyToAddress(bytes memory _publicKey) private pure returns (address) {
979-
uint256 mask = 2**(8 * 21) - 1;
980-
uint256 value = uint256(keccak256(_publicKey));
981-
return address(value & mask);
982-
}
983982
}

test/staking/general.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect, use } from 'chai'
22
import { Event, Wallet } from 'ethers'
3-
import { BigNumber } from 'ethers/utils'
3+
import { computePublicKey, BigNumber } from 'ethers/utils'
44
import { AddressZero } from 'ethers/constants'
55
import { solidity } from 'ethereum-waffle'
66

@@ -526,6 +526,20 @@ describe('Staking', () => {
526526
await expect(tx).to.be.revertedWith('Allocation: cannot allocate zero tokens')
527527
})
528528

529+
it('reject allocate with invalid public key', async function() {
530+
const invalidChannelPubKey = computePublicKey(channelPubKey, true)
531+
const tx = staking
532+
.connect(indexer)
533+
.allocate(
534+
subgraphDeploymentID,
535+
toGRT('100'),
536+
invalidChannelPubKey,
537+
channelProxy.address,
538+
price,
539+
)
540+
await expect(tx).to.be.revertedWith('Allocation: invalid channel public key')
541+
})
542+
529543
context('> when allocated', function() {
530544
beforeEach(async function() {
531545
await allocate(toGRT('10'))

0 commit comments

Comments
 (0)