diff --git a/src/main/scala/rosen/bridge/scripts/RepoConfig.es b/src/main/scala/rosen/bridge/scripts/RepoConfig.es index 2c3b492..d924329 100644 --- a/src/main/scala/rosen/bridge/scripts/RepoConfig.es +++ b/src/main/scala/rosen/bridge/scripts/RepoConfig.es @@ -1,7 +1,7 @@ { // ----------------- REGISTERS // R4: Coll[Long] = [Commitment RWT count, Watcher quorum percentage, approval offset, maximum needed approval, - // Collateral Erg amount, Collateral Rsn Amount, Total repo count] + // Collateral Erg amount, Collateral Rsn Amount] // (Minimum number of commitments needed for an event is: // min(R4[3], R4[1] * (total number of watchers) / 100 + R4[2])) // ----------------- TOKENS diff --git a/src/main/scala/rosen/bridge/scripts/RwtRepo.es b/src/main/scala/rosen/bridge/scripts/RwtRepo.es index d63a367..187e5d9 100644 --- a/src/main/scala/rosen/bridge/scripts/RwtRepo.es +++ b/src/main/scala/rosen/bridge/scripts/RwtRepo.es @@ -20,6 +20,7 @@ val repoReplication = allOf( Coll( repoOut.propositionBytes == repo.propositionBytes, + repoOut.value >= repo.value, repoOut.tokens(0)._1 == repo.tokens(0)._1, repoOut.tokens(0)._2 == repo.tokens(0)._2, repoOut.tokens(1)._1 == repo.tokens(1)._1, diff --git a/src/test/scala/contracts/ContractTest.scala b/src/test/scala/contracts/ContractTest.scala index c967d18..f1d00f8 100644 --- a/src/test/scala/contracts/ContractTest.scala +++ b/src/test/scala/contracts/ContractTest.scala @@ -180,8 +180,9 @@ class ContractTest extends TestSuite { networkConfig._1.ergoClient.execute(ctx => { val prover = getProver() val userBox = Boxes.createBoxForUser(ctx, prover.getAddress, 2e9.toLong, new ErgoToken(networkConfig._3.RSN, 200L)) - val repoConfig = Boxes.createRepoConfigsInput(ctx) - val repoBox = Boxes.createRepoInput(ctx, 100000, 5801L, 100L, 0) + val repoConfig = Boxes.createRepoConfigsWithList(ctx, Boxes.getRandomHexString(), Array(10L, 51L, 0L, 9999L, 1e9.toLong, 100)) + .convertToInputWith(Boxes.getRandomHexString(), 1) + val repoBox = Boxes.createRepoInput(ctx, 100000, 5801L, 100L, 1) val repoOut = Boxes.createRepo(ctx, 99900, 5901L, 99L, 2) val permitBox = Boxes.createPermitBox(ctx, 100L, repoBox.getId.getBytes) val WID = Boxes.createBoxCandidateForUser(ctx, prover.getAddress, Configs.minBoxValue, new ErgoToken(repoBox.getId.getBytes, 3L)) @@ -198,6 +199,41 @@ class ContractTest extends TestSuite { }) } + /** + * @target get permit transaction signing should throw error when repo value decreased in transaction + * @dependencies + * @scenario + * - mock user input + * - mock input repo box with 1e10 value + * - mock valid repoConfig box as data input + * - mock valid output repo box with 1e9 value + * - mock valid output wid, collateral and permit box + * - build and sign the get permit transaction + * @expected + * - sign error since 1e9 is less than 1e10 + */ + property("get permit transaction signing should throw error when repo value decreased in transaction") { + networkConfig._1.ergoClient.execute(ctx => { + val prover = getProver() + val userBox = Boxes.createBoxForUser(ctx, prover.getAddress, 2e9.toLong, new ErgoToken(networkConfig._3.RSN, 200L)) + val repoConfig = Boxes.createRepoConfigsInput(ctx) + val repoBox = Boxes.createRepoInput(ctx, 100000, 5801L, 100L, 1, 1e10.toLong) + val repoOut = Boxes.createRepo(ctx, 99900, 5901L, 99L, 2, 1e9.toLong) + val permitBox = Boxes.createPermitBox(ctx, 100L, repoBox.getId.getBytes) + val WID = Boxes.createBoxCandidateForUser(ctx, prover.getAddress, Configs.minBoxValue, new ErgoToken(repoBox.getId.getBytes, 3L)) + val watcherCollateral = Boxes.createWatcherCollateralBox(ctx, 1e9.toLong, 100, repoBox.getId.getBytes, 100) + val tx = ctx.newTxBuilder().addInputs(repoBox, userBox) + .fee(Configs.fee) + .addDataInputs(repoConfig) + .addOutputs(repoOut, watcherCollateral, permitBox, WID) + .sendChangeTo(prover.getAddress) + .build() + assertThrows[AnyRef] { + prover.sign(tx) + } + }) + } + /** * @target get permit transaction signing should throw error when creating a fake collateral not containing AWC * @dependencies diff --git a/src/test/scala/testUtils/Boxes.scala b/src/test/scala/testUtils/Boxes.scala index cddcbba..b7e332b 100644 --- a/src/test/scala/testUtils/Boxes.scala +++ b/src/test/scala/testUtils/Boxes.scala @@ -176,10 +176,11 @@ object Boxes { nftId: String, rwtId: String, awcId: String, + value: Long = Configs.minBoxValue, ): OutBox = { val txB = ctx.newTxBuilder() val repoBuilder = txB.outBoxBuilder() - .value(Configs.minBoxValue) + .value(value) .tokens( new ErgoToken(nftId, 1), new ErgoToken(rwtId, RWTCount), @@ -226,8 +227,9 @@ object Boxes { RSNCount: Long, AwcCount: Long, watcherCount: Long, + value: Long = Configs.minBoxValue, ): OutBox = { - createRepoWithTokens(ctx, RWTCount, RSNCount, AwcCount, watcherCount, networkConfig._3.RepoNFT, networkConfig._2.tokens.RWTId, networkConfig._2.tokens.AwcNFT) + createRepoWithTokens(ctx, RWTCount, RSNCount, AwcCount, watcherCount, networkConfig._3.RepoNFT, networkConfig._2.tokens.RWTId, networkConfig._2.tokens.AwcNFT, value) } def createRepoInput( @@ -236,8 +238,9 @@ object Boxes { RSNCount: Long, AwcCount: Long, watcherCount: Long, + value: Long = Configs.minBoxValue, ): InputBox = { - createRepo(ctx, RWTCount, RSNCount, AwcCount, watcherCount).convertToInputWith(Boxes.getRandomHexString(), 0) + createRepo(ctx, RWTCount, RSNCount, AwcCount, watcherCount, value).convertToInputWith(Boxes.getRandomHexString(), 0) } def createPermitBox(ctx: BlockchainContext, RWTCount: Long, WID: Array[Byte], tokens: ErgoToken*): OutBox = {