Don't: Do not call onBoard on a value that has not previously had offBoard called on it
contract BadContract {
ctUint64 public sum;
//...
function addWithoutCarefulOnboard() public {
gtUint64 a = MpcCore.setPublic64(1);
gtUint64 sum_ = MpcCore.onBoard(sum); // THIS WILL REVERT
sum_ = MpcCore.add(sum_, a);
sum = MpcCore.offBoard(sum_);
}
//...
}
Do: Initialize the value by calling offBoard inside the constructor
contract GoodContract {
ctUint64 public sum;
constructor() {
// By initializing sum with an encrypted value, we ensure
// calling onBoard on sum does not revert
gtUint64 sum_ = MpcCore.setPublic64(0);
sum = MpcCore.offBoard(sum_);
}
//...
function add() public {
gtUint64 a = MpcCore.setPublic64(1);
gtUint64 sum_ = MpcCore.onBoard(sum);
sum_ = MpcCore.add(sum_, a);
sum = MpcCore.offBoard(sum_);
}
//...
}
Or:Check if the value is zero before calling onBoard
contract GoodContract {
ctUint64 public sum;
//...
function addWithCarefulOnboard() public {
gtUint64 a = MpcCore.setPublic64(1);
gtUint64 sum_;
// By checking if sum is equal to zero, we can verify whether
// or not it is safe to call onBoard on sum
if (ctUint64.unwrap(sum) == 0) {
sum_ = MpcCore.setPublic64(0);
} else {
sum_ = MpcCore.onBoard(sum);
}
sum_ = MpcCore.add(sum_, a);
sum = MpcCore.offBoard(sum_);
}
//...
}