diff --git a/packages/vouching/contracts/Vouching.sol b/packages/vouching/contracts/Vouching.sol index 8727b9220..9036ce3cf 100644 --- a/packages/vouching/contracts/Vouching.sol +++ b/packages/vouching/contracts/Vouching.sol @@ -29,6 +29,7 @@ contract Vouching is Initializable { } mapping (string => Dependency) private _registry; + mapping (string => bool) private _takenDependencyNames; uint256 private _minimumStake; ERC20 private _token; @@ -63,8 +64,9 @@ contract Vouching is Initializable { require(initialStake >= _minimumStake, "Initial stake must be equal or greater than minimum stake"); require(owner != address(0), "Owner address cannot be zero"); require(dependencyAddress != address(0), "Dependency address cannot be zero"); - require(_registry[name].dependencyAddress == address(0), "Given dependency name is already registered"); + require(!_takenDependencyNames[name], "Given dependency name is already registered"); + _takenDependencyNames[name] = true; _registry[name] = Dependency(owner, dependencyAddress, initialStake); _token.safeTransferFrom(owner, this, initialStake); @@ -97,7 +99,11 @@ contract Vouching is Initializable { function remove(string name) external onlyDependencyOwner(name) { // Owner surrenders _minimumStake to the system uint256 reimbursedAmount = _registry[name].stake.sub(_minimumStake); + + // The entry is not removed from _takenDependencyNames, to prevent a new dependecy + // from reusing the same name delete _registry[name]; + _token.safeTransfer(msg.sender, reimbursedAmount); emit DependencyRemoved(keccak256(abi.encodePacked(name))); } diff --git a/packages/vouching/test/contracts/Vouching.test.js b/packages/vouching/test/contracts/Vouching.test.js index d79d82ade..20a7e5ecb 100644 --- a/packages/vouching/test/contracts/Vouching.test.js +++ b/packages/vouching/test/contracts/Vouching.test.js @@ -288,6 +288,15 @@ contract('Vouching', function ([_, tokenOwner, vouchingOwner, developer, transfe amount.should.be.bignumber.equal(0); }); + it('reverts when a removed dependency\'s name is reutilized', async function () { + await this.vouching.remove(dependencyName, { from: developer }); + await assertRevert( + this.vouching.create( + dependencyName, developer, anotherDependencyAddress, stakeAmount, { from: developer } + ) + ); + }); + it('emits a DependencyRemoved event', async function () { const result = await this.vouching.remove(dependencyName, { from: developer }); assertEvent.inLogs(result.logs, 'DependencyRemoved', {