Skip to content

Commit 95b6908

Browse files
committed
test: add unit tests for stack-extend
1 parent ae19162 commit 95b6908

File tree

3 files changed

+267
-0
lines changed

3 files changed

+267
-0
lines changed

contrib/boot-contracts-unit-tests/contracts/indirect.clar

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818
(contract-call? 'ST000000000000000000002AMW42H.pox-4 stack-increase increase-by signer-sig signer-key max-amount auth-id)
1919
)
2020

21+
(define-public (stack-extend (extend-count uint)
22+
(pox-addr { version: (buff 1), hashbytes: (buff 32) })
23+
(signer-sig (optional (buff 65)))
24+
(signer-key (buff 33))
25+
(max-amount uint)
26+
(auth-id uint))
27+
(contract-call? 'ST000000000000000000002AMW42H.pox-4 stack-extend extend-count pox-addr signer-sig signer-key max-amount auth-id)
28+
)
29+
2130
(define-public (delegate-stx (amount-ustx uint)
2231
(delegate-to principal)
2332
(until-burn-ht (optional uint))

contrib/boot-contracts-unit-tests/tests/helpers.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,43 @@ export const stackIncrease = (
221221
);
222222
};
223223

224+
export const stackExtend = (
225+
stacker: StackerInfo,
226+
extendCount: bigint | number,
227+
maxAmount: bigint | number,
228+
authId: bigint | number,
229+
sender: string
230+
) => {
231+
const rewardCycle = burnHeightToRewardCycle(simnet.blockHeight);
232+
const sigArgs = {
233+
authId,
234+
maxAmount,
235+
rewardCycle,
236+
period: Number(extendCount),
237+
topic: Pox4SignatureTopic.StackExtend,
238+
poxAddress: stacker.btcAddr,
239+
signerPrivateKey: stacker.signerPrivKey,
240+
};
241+
const signerSignature = stacker.client.signPoxSignature(sigArgs);
242+
const signerKey = Cl.bufferFromHex(stacker.signerPubKey);
243+
244+
const stackExtendArgs = [
245+
Cl.uint(extendCount),
246+
poxAddressToTuple(stacker.btcAddr),
247+
Cl.some(Cl.bufferFromHex(signerSignature)),
248+
signerKey,
249+
Cl.uint(maxAmount),
250+
Cl.uint(authId),
251+
];
252+
253+
return simnet.callPublicFn(
254+
POX_CONTRACT,
255+
"stack-extend",
256+
stackExtendArgs,
257+
sender
258+
);
259+
};
260+
224261
export const delegateStx = (
225262
amount: bigint | number,
226263
delegateTo: string,

contrib/boot-contracts-unit-tests/tests/solo-stacker.test.ts

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
delegateStackStx,
1212
delegateStx,
1313
getPoxInfo,
14+
stackExtend,
1415
stackIncrease,
1516
stackStx,
1617
stackers,
@@ -887,6 +888,226 @@ describe("pox-4", () => {
887888
);
888889
expect(result).toBeErr(Cl.int(26));
889890
});
891+
892+
it("cannot be called indirectly from an unauthorized caller", () => {
893+
const account = stackers[0];
894+
const burnBlockHeight = 1;
895+
const authId = account.authId;
896+
const period = 2;
897+
898+
stackStx(
899+
account,
900+
maxAmount,
901+
burnBlockHeight,
902+
period,
903+
maxAmount,
904+
authId,
905+
account.stxAddress
906+
);
907+
908+
const rewardCycle = burnHeightToRewardCycle(simnet.blockHeight);
909+
const sigArgs = {
910+
authId,
911+
maxAmount,
912+
rewardCycle,
913+
period,
914+
topic: Pox4SignatureTopic.StackExtend,
915+
poxAddress: account.btcAddr,
916+
signerPrivateKey: account.signerPrivKey,
917+
};
918+
const signerSignature = account.client.signPoxSignature(sigArgs);
919+
const signerKey = Cl.bufferFromHex(account.signerPubKey);
920+
921+
const stackExtendArgs = [
922+
Cl.uint(2),
923+
poxAddressToTuple(account.btcAddr),
924+
Cl.some(Cl.bufferFromHex(signerSignature)),
925+
signerKey,
926+
Cl.uint(maxAmount),
927+
Cl.uint(authId),
928+
];
929+
const response = simnet.callPublicFn(
930+
"indirect",
931+
"stack-extend",
932+
stackExtendArgs,
933+
address1
934+
);
935+
936+
expect(response.result).toBeErr(
937+
Cl.int(ERRORS.ERR_STACKING_PERMISSION_DENIED)
938+
);
939+
});
940+
941+
it("can be called indirectly from an authorized caller", () => {
942+
const account = stackers[0];
943+
const burnBlockHeight = 1;
944+
const authId = account.authId;
945+
const period = 2;
946+
const poxInfo = getPoxInfo();
947+
const cycleLength = Number(poxInfo.rewardCycleLength);
948+
949+
allowContractCaller(`${deployer}.indirect`, null, address1);
950+
951+
stackStx(
952+
account,
953+
maxAmount,
954+
burnBlockHeight,
955+
period,
956+
maxAmount,
957+
authId,
958+
account.stxAddress
959+
);
960+
961+
const rewardCycle = burnHeightToRewardCycle(simnet.blockHeight);
962+
const sigArgs = {
963+
authId,
964+
maxAmount,
965+
rewardCycle,
966+
period,
967+
topic: Pox4SignatureTopic.StackExtend,
968+
poxAddress: account.btcAddr,
969+
signerPrivateKey: account.signerPrivKey,
970+
};
971+
const signerSignature = account.client.signPoxSignature(sigArgs);
972+
const signerKey = Cl.bufferFromHex(account.signerPubKey);
973+
974+
const stackExtendArgs = [
975+
Cl.uint(2),
976+
poxAddressToTuple(account.btcAddr),
977+
Cl.some(Cl.bufferFromHex(signerSignature)),
978+
signerKey,
979+
Cl.uint(maxAmount),
980+
Cl.uint(authId),
981+
];
982+
const response = simnet.callPublicFn(
983+
"indirect",
984+
"stack-extend",
985+
stackExtendArgs,
986+
address1
987+
);
988+
989+
expect(response.result).toBeOk(
990+
Cl.tuple({
991+
stacker: Cl.principal(account.stxAddress),
992+
"unlock-burn-height": Cl.uint(5 * cycleLength),
993+
})
994+
);
995+
});
996+
997+
it("cannot extend for 0 cycles", () => {
998+
const account = stackers[0];
999+
const burnBlockHeight = 1;
1000+
const authId = account.authId;
1001+
const period = 2;
1002+
1003+
stackStx(
1004+
account,
1005+
maxAmount,
1006+
burnBlockHeight,
1007+
period,
1008+
maxAmount,
1009+
authId,
1010+
account.stxAddress
1011+
);
1012+
const { result } = stackExtend(
1013+
account,
1014+
0,
1015+
maxAmount,
1016+
authId,
1017+
account.stxAddress
1018+
);
1019+
1020+
expect(result).toBeErr(Cl.int(ERRORS.ERR_STACKING_INVALID_LOCK_PERIOD));
1021+
});
1022+
1023+
it("errors if not directly stacking", () => {
1024+
const account = stackers[0];
1025+
const delegateAccount = stackers[1];
1026+
const authId = account.authId;
1027+
const period = 6;
1028+
1029+
delegateStx(
1030+
maxAmount,
1031+
delegateAccount.stxAddress,
1032+
null,
1033+
null,
1034+
account.stxAddress
1035+
);
1036+
delegateStackStx(
1037+
address1,
1038+
maxAmount,
1039+
delegateAccount.btcAddr,
1040+
1000,
1041+
period,
1042+
address2
1043+
);
1044+
1045+
const { result } = stackExtend(
1046+
account,
1047+
4,
1048+
maxAmount,
1049+
authId,
1050+
account.stxAddress
1051+
);
1052+
expect(result).toBeErr(Cl.int(ERRORS.ERR_STACKING_IS_DELEGATED));
1053+
});
1054+
1055+
it("can change the pox address", () => {
1056+
const account = stackers[0];
1057+
const account1 = stackers[1];
1058+
const burnBlockHeight = 1;
1059+
const authId = account.authId;
1060+
const period = 6;
1061+
const extendPeriod = 5;
1062+
const poxInfo = getPoxInfo();
1063+
const cycleLength = Number(poxInfo.rewardCycleLength);
1064+
1065+
stackStx(
1066+
account,
1067+
maxAmount,
1068+
burnBlockHeight,
1069+
period,
1070+
maxAmount,
1071+
authId,
1072+
account.stxAddress
1073+
);
1074+
1075+
const rewardCycle = burnHeightToRewardCycle(simnet.blockHeight);
1076+
const sigArgs = {
1077+
authId,
1078+
maxAmount,
1079+
rewardCycle,
1080+
period: extendPeriod,
1081+
topic: Pox4SignatureTopic.StackExtend,
1082+
poxAddress: account1.btcAddr,
1083+
signerPrivateKey: account.signerPrivKey,
1084+
};
1085+
const signerSignature = account.client.signPoxSignature(sigArgs);
1086+
const signerKey = Cl.bufferFromHex(account.signerPubKey);
1087+
1088+
const stackExtendArgs = [
1089+
Cl.uint(extendPeriod),
1090+
poxAddressToTuple(account1.btcAddr),
1091+
Cl.some(Cl.bufferFromHex(signerSignature)),
1092+
signerKey,
1093+
Cl.uint(maxAmount),
1094+
Cl.uint(authId),
1095+
];
1096+
1097+
const { result } = simnet.callPublicFn(
1098+
POX_CONTRACT,
1099+
"stack-extend",
1100+
stackExtendArgs,
1101+
address1
1102+
);
1103+
1104+
expect(result).toBeOk(
1105+
Cl.tuple({
1106+
stacker: Cl.principal(account.stxAddress),
1107+
"unlock-burn-height": Cl.uint(12 * cycleLength),
1108+
})
1109+
);
1110+
});
8901111
});
8911112

8921113
describe("stack-increase", () => {

0 commit comments

Comments
 (0)