Skip to content

Commit 8b7bc8a

Browse files
archseerjadepark-devkrebernisakpatricios-spaceogtownsend
authored
Tolk 1.2 (#359)
* Tolk 1.2 * Fix pendingOwner serialization * Fix maybeAddr serialization in typescript wrappers * Fix go bindings * nix: Bump sha * Fix more cases * chore: bump mylocalton * tolk-1-2-mylocalton-fix (#387) * MCMS suite polish/fixes #3 (#360) * Allow MCMS<T>.submitErrorReport even when root is expired * Timelock.onBouncedMessage - Mark the operation as final * Adopt SnakedCell<T> * Timelock - support blocking msg bodies (data) < 32 bits * Revert - 'Timelock - support blocking msg bodies (data) < 32 bits' * Use SnakedCell<RootDescriptor> for roots * Add scripts/disk-cache-gc.sh run to e2e test (#366) * Add scripts/disk-cache-gc.sh run to e2e test * Relocate Nix store to /mnt * chore: remove unused function (#368) * Dont cache CI test run logs (#377) * dont cache test logs * chore: clean log dir before running test * fix: flag --------- Co-authored-by: Jade Park <jadepark.dev@gmail.com> * Bump core version tag (#381) * refactor: offramp wrappers to use CellCodec (#379) * replace all encode and decode functions with builder type * refactor message encoding as well * Update contracts/wrappers/ccip/OffRamp.ts Co-authored-by: Kristijan Rebernisak <kristijan.rebernisak@gmail.com> * Update contracts/wrappers/ccip/OffRamp.ts Co-authored-by: Kristijan Rebernisak <kristijan.rebernisak@gmail.com> * fmt * fix typo --------- Co-authored-by: Kristijan Rebernisak <kristijan.rebernisak@gmail.com> * refactor ton accessor ocr3base binding (#384) * refactor offramp binding and chain accessor ocr3base * update comments * fix lint * fix contract test * add chainId back * golint * [NONEVM-3047] feat: add feeValueJuels to getValidatedFee and TVM2ANY event (#361) * feat: add feeValueJuels to getValidatedFee * fix: missed overwritten param * fix: update feequoter go bindings * fix: update onramp go bindings * fix: golint * fix: revert unnecesary change * feat: don't fail on missing link token price * cicd: power up integration test vm * test: make feequoter errors work * Fix errorCodes for feeQuoter * LINK token price also needs configuring * Update generated feeQuoter exit codes --------- Co-authored-by: Blaž Hrastnik <blaz@mxxn.io> * NONEVM-2403: use CLDF for ton localnet access (#373) * chore: clean up * chore: bump core * chore: bump core/deployment * chore: tidy * chore: clean up * chore: bump core * chore: bump mylocalton * chore: modgraph * Fix compilation on 1.2 * fix import * fix: wait for current masterchain block --------- Co-authored-by: Kristijan Rebernisak <kristijan.rebernisak@gmail.com> Co-authored-by: Patricio <contact@patricios.space> Co-authored-by: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Co-authored-by: vicentevieytes <73846744+vicentevieytes@users.noreply.github.com> Co-authored-by: Joe Huang <joe.huang@smartcontract.com> Co-authored-by: Blaž Hrastnik <blaz@mxxn.io> * fix import yet again * Address review * Update sha --------- Co-authored-by: Jade Park <jadepark.dev@gmail.com> Co-authored-by: Kristijan Rebernisak <kristijan.rebernisak@gmail.com> Co-authored-by: Patricio <contact@patricios.space> Co-authored-by: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Co-authored-by: vicentevieytes <73846744+vicentevieytes@users.noreply.github.com> Co-authored-by: Joe Huang <joe.huang@smartcontract.com>
1 parent 57cc1c0 commit 8b7bc8a

38 files changed

Lines changed: 337 additions & 767 deletions

File tree

contracts/contracts/ccip/common/cross_chain_address_validation.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import "types"
44

5-
tolk 1.1
5+
tolk 1.2
66

77
const EVM_PRECOMPILE_SPACE = 1024;
88
const APTOS_PRECOMPILE_SPACE = 0x0b;

contracts/contracts/ccip/fee_quoter/contract.tolk

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,10 @@ fun calculateValidatedFee(msg: Router_CCIPSend): Fee {
240240
var destChainConfig = destChainConfigResult.loadValue();
241241

242242
assert(destChainConfig.config.isEnabled, FeeQuoter_Error.DestChainNotEnabled);
243-
244-
val premiumMultiplier = st.premiumMultiplierWeiPerEth.mustGet(msg.feeToken, FeeQuoter_Error.FeeTokenNotSupported as int);
245-
val feeTokenPrice = st.usdPerToken.mustGet(msg.feeToken, FeeQuoter_Error.FeeTokenNotSupported as int);
243+
assert(msg.feeToken != null, FeeQuoter_Error.FeeTokenNotSupported);
244+
val feeToken = msg.feeToken!;
245+
val premiumMultiplier = st.premiumMultiplierWeiPerEth.mustGet(feeToken, FeeQuoter_Error.FeeTokenNotSupported as int);
246+
val feeTokenPrice = st.usdPerToken.mustGet(feeToken, FeeQuoter_Error.FeeTokenNotSupported as int);
246247

247248
val it = (msg.data as SnakedCell<uint8>).iter();
248249
val (msgDataLen, errorCode) = it.countBytesSafe();
@@ -297,17 +298,17 @@ fun calculateValidatedFee(msg: Router_CCIPSend): Fee {
297298
val feeTokenAmount = (feeTokenValue / feeTokenPrice.value);
298299

299300
// Equivalent to processMessageArgs in Solidity FeeQuoter
300-
val feeValueJuels = calculateFeeValueJuels(st, msg, feeTokenValue, feeTokenAmount);
301+
val feeValueJuels = calculateFeeValueJuels(st, feeToken, feeTokenValue, feeTokenAmount);
301302

302303
return Fee {
303304
feeTokenAmount: mustCastToCoin(feeTokenAmount, FeeQuoter_Error.FeeOverflow as int),
304305
feeValueJuels: feeValueJuels as uint96, // safe because already checked against maxFeeJuelsPerMsg
305306
};
306307
}
307308

308-
fun calculateFeeValueJuels(st: Storage, msg: Router_CCIPSend, feeTokenValue: coins, feeTokenAmount: coins): coins {
309+
fun calculateFeeValueJuels(st: Storage, feeToken: address, feeTokenValue: coins, feeTokenAmount: coins): coins {
309310
var feeValueJuels = feeTokenAmount;
310-
if (msg.feeToken != st.linkToken) {
311+
if (feeToken != st.linkToken) {
311312
val linkTokenPriceResult = st.usdPerToken.get(st.linkToken);
312313
if (!linkTokenPriceResult.isFound) {
313314
return 0;

contracts/contracts/ccip/offramp/contract.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ configuration and emits a DYNAMIC_CONFIG_SET_TOPIC event.
774774
fun onSetDynamicConfig(msg: OffRamp_SetDynamicConfig) {
775775
var st = Storage.load();
776776

777-
assert(!msg.feeQuoter.isNone()) throw Error.ZeroAddressNotAllowed;
777+
// NOTE: address now is guaranteed to be non-zero, address? allows zero
778778

779779
st.feeQuoter = msg.feeQuoter;
780780
st.permissionlessExecutionThresholdSeconds = msg.permissionlessExecutionThresholdSeconds;

contracts/contracts/ccip/onramp/contract.tolk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tolk 1.1
1+
tolk 1.2
22

33
import "types"
44
import "events"
@@ -297,7 +297,7 @@ fun onExecutorFinishedSuccessfully(st: OnRamp_Storage, msg: OnRamp_ExecutorFinis
297297
data: ccipsend.data,
298298
extraArgs: ccipsend.extraArgs,
299299
tokenAmounts: ccipsend.tokenAmounts,
300-
feeToken: ccipsend.feeToken,
300+
feeToken: ccipsend.feeToken!, // guaranteed to be non-null by this point
301301
feeTokenAmount: msg.fee.feeTokenAmount as uint256, // safe because it is 120 bits
302302
}.toCell(),
303303
feeValueJuels: msg.fee.feeValueJuels,

contracts/contracts/ccip/router/contract.tolk

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,7 @@ fun onCCIPSend(msg: Router_CCIPSend, sender: address, value: coins) {
425425
val isCursed = rmn.cursedSubjects.isCursed(msg.destChainSelector as uint128);
426426
assert(!isCursed, Router_Error.SubjectCursed);
427427

428-
// TODO: the feeToken typing will need to change to `address?` and comparing with `null` in upcoming Tolk 1.2
429-
if (msg.feeToken.isNone()) {
428+
if (msg.feeToken == null) {
430429
msg.feeToken = st.wrappedNative
431430
}
432431

contracts/contracts/ccip/router/messages.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct (0x31768d95) Router_CCIPSend {
4646
receiver: CrossChainAddress;
4747
data: cell;
4848
tokenAmounts: SnakedCell<TokenAmount>;
49-
feeToken: address;
49+
feeToken: address?;
5050
extraArgs: cell;
5151
}
5252

contracts/contracts/examples/counter.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tolk 1.1
1+
tolk 1.2
22

33
import "@stdlib/common.tolk"
44
import "../lib/utils.tolk"

contracts/contracts/lib/access/access_control.tolk

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tolk 1.1
1+
tolk 1.2
22

33
import "../utils.tolk";
44

@@ -311,17 +311,17 @@ fun AccessControl<T>.getRoleAdmin(self, role: int): int {
311311
///
312312
/// Role bearers are not sorted in any particular way, and their ordering may change at any point.
313313
@inline
314-
fun AccessControl<T>.getRoleMember(self, role: int, index: uint32): address {
314+
fun AccessControl<T>.getRoleMember(self, role: int, index: uint32): address? {
315315
// Check if the role is valid
316316
val data = self.data.roles.get(role);
317317
if (!data.isFound) {
318-
return createAddressNone(); // role does not exist
318+
return null; // role does not exist
319319
}
320320

321321
// Check if the account exists in the role data
322322
var d = lazy AccessControl_RoleData.fromCell(data.loadValue());
323323
if (index >= d.membersLen) {
324-
return createAddressNone(); // index out of bounds
324+
return null; // index out of bounds
325325
}
326326

327327
// Notice: we need to iterate through the dictionary to get the account at the specified index.
@@ -353,16 +353,16 @@ fun AccessControl<T>.getRoleMemberCount(self, role: int): int {
353353
}
354354

355355
@inline
356-
fun AccessControl<T>.getRoleMemberFirst(self, role: int): address {
356+
fun AccessControl<T>.getRoleMemberFirst(self, role: int): address? {
357357
// Check if the role is valid
358358
val data = self.data.roles.get(role);
359359
if (!data.isFound) {
360-
return createAddressNone(); // role does not exist
360+
return null; // role does not exist
361361
}
362362

363363
val d = lazy AccessControl_RoleData.fromCell(data.loadValue());
364364
if (d.membersLen == 0) {
365-
return createAddressNone(); // no members in the role
365+
return null; // no members in the role
366366
}
367367

368368
// Get the first account in the role data
@@ -371,18 +371,18 @@ fun AccessControl<T>.getRoleMemberFirst(self, role: int): address {
371371
}
372372

373373
@inline
374-
fun AccessControl<T>.getRoleMemberNext(self, role: int, pivot: address): address {
374+
fun AccessControl<T>.getRoleMemberNext(self, role: int, pivot: address): address? {
375375
// Check if the role is valid
376376
val data = self.data.roles.get(role);
377377
if (!data.isFound) {
378-
return createAddressNone(); // role does not exist
378+
return null; // role does not exist
379379
}
380380

381381
// Get the next account in the role data after the pivot
382382
val d = lazy AccessControl_RoleData.fromCell(data.loadValue());
383383
var acc = d.hasRole.findKeyGreater(pivot);
384384
if (!acc.isFound) {
385-
return createAddressNone(); // no next account
385+
return null; // no next account
386386
}
387387

388388
return acc.getKey();

contracts/contracts/lib/crypto/merkle_proof.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tolk 1.1
1+
tolk 1.2
22

33
import "../utils.tolk"
44

contracts/contracts/mcms/mcms.tolk

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tolk 1.1
1+
tolk 1.2
22

33
import "../lib/utils";
44
import "../lib/secp256k1";
@@ -586,7 +586,7 @@ struct OpPendingInfo {
586586
/// The timeout required to finalize the currently executing op
587587
opFinalizationTimeout: uint32;
588588
/// The address that the (pending) operation was sent to (and could bounce from).
589-
opPendingReceiver: address;
589+
opPendingReceiver: address?;
590590
/// The truncated body of the pending operation (256 bits from the original message),
591591
/// stored as the next expected potential bounce, and verified in onBounceMessage handler.
592592
opPendingBodyTruncated: uint256;
@@ -872,7 +872,7 @@ fun MCMS<T>.setRoot(
872872
opPendingInfo: OpPendingInfo{
873873
validAfter: blockchain.now(), // immediate
874874
opFinalizationTimeout: opPendingInfo.opFinalizationTimeout, // cp from storage
875-
opPendingReceiver: createAddressNone(),
875+
opPendingReceiver: null,
876876
opPendingBodyTruncated: 0,
877877
}.toCell()
878878
},
@@ -1183,7 +1183,7 @@ fun MCMS<T>.setConfig(
11831183
opPendingInfo: OpPendingInfo{
11841184
validAfter: blockchain.now(), // immediate
11851185
opFinalizationTimeout: opPendingInfo.opFinalizationTimeout, // cp from storage
1186-
opPendingReceiver: createAddressNone(),
1186+
opPendingReceiver: null,
11871187
opPendingBodyTruncated: 0
11881188
}.toCell()
11891189
},
@@ -1291,7 +1291,9 @@ fun MCMS<T>.submitErrorReport(
12911291
// Check the reported error against the stored pending operation
12921292
val opPendingInfo = lazy OpPendingInfo.fromCell(rootInfo.expiringRootAndOpCount.opPendingInfo);
12931293

1294-
val matchesPendingOp = opPendingInfo.opPendingReceiver == op.to
1294+
val matchesPendingOp =
1295+
opPendingInfo.opPendingReceiver != null
1296+
&& opPendingInfo.opPendingReceiver == op.to
12951297
&& opPendingInfo.opPendingBodyTruncated == extractBouncedBody(op.data.beginParse());
12961298

12971299
// Store the root in a separate cell (size limit)
@@ -1499,7 +1501,7 @@ fun onBouncedMessage(in: InMessageBounced) {
14991501
//
15001502
// @dev on setRoot the OpPendingInfo is cleared, so a bounce from an old root will not match
15011503
val bouncedBody = extractBouncedBody(in.bouncedBody.skipBouncedPrefix());
1502-
if (opPendingInfo.opPendingReceiver != in.senderAddress
1504+
if (opPendingInfo.opPendingReceiver! != in.senderAddress
15031505
|| opPendingInfo.opPendingBodyTruncated != bouncedBody) {
15041506

15051507
// Check the case when a new root was just set and no ops yet executed
@@ -1518,7 +1520,7 @@ fun onBouncedMessage(in: InMessageBounced) {
15181520
// If the received bounce equals expected, revert state (allow op retry)
15191521
rootInfo.expiringRootAndOpCount.opCount = rootInfo.expiringRootAndOpCount.opCount - 1;
15201522
opPendingInfo.validAfter = blockchain.now(); // can be retried immediately
1521-
opPendingInfo.opPendingReceiver = createAddressNone();
1523+
opPendingInfo.opPendingReceiver = null;
15221524
opPendingInfo.opPendingBodyTruncated = 0;
15231525

15241526
rootInfo.expiringRootAndOpCount.opPendingInfo = opPendingInfo.toCell();

0 commit comments

Comments
 (0)