diff --git a/ride/multisig.ride b/ride/multisig.ride index e7d4c63f..5bdad0e2 100644 --- a/ride/multisig.ride +++ b/ride/multisig.ride @@ -32,16 +32,24 @@ func validatePublicKey(publicKey: String) = { fromBase58String(publicKey).size() == publicKeySize } +func validateOwner(owners: List[String], pk: String) = { + strict checks = [ + validatePublicKey(pk) || throwErr("invalid owner public key"), + owners.indexOf(pk) == owners.lastIndexOf(pk) || throwErr("must not contain duplicates") + ] + + owners +} + @Callable(i) func init(owners: List[String], quorum: Int) = { - func validateOwner(acc: Unit, pk: String) = validatePublicKey(pk) || throwErr("invalid owner public key") strict checks = [ i.caller == this || throwErr("init: not allowed"), !getString(kMultisig).isDefined() || throwErr("init: already initialized"), (owners.size() > 0 && owners.size() <= maxOwners) || throwErr("init: invalid owners"), (quorum > 0 && quorum <= owners.size()) || throwErr("init: invalid quorum"), # maxOwners - FOLD<10>(owners, unit, validateOwner) + FOLD<10>(owners, owners, validateOwner) ] ([ diff --git a/test/components/multisig/init.spec.mjs b/test/components/multisig/init.spec.mjs index ca68a384..839686f4 100644 --- a/test/components/multisig/init.spec.mjs +++ b/test/components/multisig/init.spec.mjs @@ -29,7 +29,7 @@ describe(`[${process.pid}] multisig: init`, () => { })).to.be.rejectedWith('not allowed'); }); - it('invalid owners', async () => { + it('should throw if owners size <= 0', async () => { const owners = []; const quorum = 0; @@ -42,6 +42,38 @@ describe(`[${process.pid}] multisig: init`, () => { })).to.be.rejectedWith('invalid owners'); }); + it('should throw if owners size > maxOwners', async () => { + const maxOwners = 10; + const owners = Array(maxOwners + 1).fill(accounts.admin0.publicKey); + const quorum = 0; + + return expect(init({ + dApp: accounts.multisig.address, + caller: accounts.multisig.seed, + owners, + quorum, + additionalFee: 4e5, + })).to.be.rejectedWith('invalid owners'); + }); + + it('should throw id there are duplicates in owners', async () => { + const owners = [ + accounts.admin0.publicKey, + accounts.admin1.publicKey, + accounts.admin1.publicKey, + accounts.admin2.publicKey, + ]; + const quorum = 3; + + return expect(init({ + dApp: accounts.multisig.address, + caller: accounts.multisig.seed, + owners, + quorum, + additionalFee: 4e5, + })).to.be.rejectedWith('must not contain duplicates'); + }); + it('invalid quorum', async () => { const owners = [accounts.admin0.publicKey]; const quorum = 0;