Omniscia Symbiosis Finance Audit

Synthesis Manual Review Findings

Synthesis Manual Review Findings

SYN-01M: Inexistent Access Control for Reverts

Description:

The revertSynthesizeRequest applies no access control on the caller, allowing arbitrary users to inspect the blockchain mempool and cancel upcoming synthesizes by front-running them with a crafted _txID.

Example:

contracts/synth-contracts/Synthesis.sol
217/**
218 * @notice Revert synthesize() operation
219 * @dev Can called only by bridge after initiation on a second chain
220 * @dev Further, this transaction also enters the relay network and is called on the other side under the method "revertSynthesize"
221 * @param _txID the synthesize transaction that was received from the event when it was originally called synthesize on the Portal contract
222 * @param _receiveSide Synthesis address on another network
223 * @param _oppositeBridge Bridge address on another network
224 * @param _chainID Chain id of the network
225 */
226function revertSynthesizeRequest(
227 uint256 _stableBridgingFee,
228 bytes32 _txID,
229 address _receiveSide,
230 address _oppositeBridge,
231 uint256 _chainID
232) external whenNotPaused {
233 bytes32 externalID = keccak256(abi.encodePacked(_txID, address(this), block.chainid));
234
235 require(
236 synthesizeStates[externalID] != SynthesizeState.Synthesized,
237 "Symb: synthetic tokens already minted"
238 );
239 synthesizeStates[externalID] = SynthesizeState.RevertRequest; // close
240
241 {
242 bytes memory out = abi.encodeWithSelector(
243 bytes4(keccak256(bytes("revertSynthesize(uint256,bytes32)"))),
244 _stableBridgingFee,
245 externalID
246 );
247 IBridge(bridge).transmitRequestV2(
248 out,
249 _receiveSide,
250 _oppositeBridge,
251 _chainID
252 );
253 }
254
255 emit RevertSynthesizeRequest(_txID, _msgSender());
256}

Recommendation:

We advise access control to be imposed here properly by allowing the function to only be invoked by the bridge as per the documentation.

Alleviation:

The external ID system now utilizes the _msgSender() argument as well thereby ensuring that the ID of a different party cannot be provided and thus alleviating this exhibit.

SYN-02M: Improper Reversion of Burn

Description:

The revertBurn function does not properly revert the burn action as the recipient of the burn operation is not reimbursed for the full amount they burned and instead the bridging fee is applied again.

Example:

contracts/synth-contracts/Synthesis.sol
394/**
395 * @notice Emergency unburn
396 * @dev Can called only by bridge after initiation on a second chain
397 * @param _txID the synthesize transaction that was received from the event when it was originally called burn on the Synthesize contract
398 */
399function revertBurn(uint256 _stableBridgingFee, bytes32 _txID) external onlyBridge whenNotPaused {
400 TxState storage txState = requests[_txID];
401 require(
402 txState.state == RequestState.Sent,
403 "Symb: state not open or tx does not exist"
404 );
405 txState.state = RequestState.Reverted;
406 // close
407 ISyntFabric(fabric).synthesize(
408 txState.recipient,
409 txState.amount - _stableBridgingFee,
410 txState.stoken
411 );
412 ISyntFabric(fabric).synthesize(
413 bridge,
414 _stableBridgingFee,
415 txState.stoken
416 );
417 emit RevertBurnCompleted(
418 _txID,
419 txState.recipient,
420 txState.amount,
421 txState.stoken
422 );
423}

Recommendation:

We advise this trait of the system to be re-evaluated and the bridge fee to potentially not be applied for emergency reversions.

Alleviation:

The Symbiosis Finance team stated that this is indeed by design as the relayers of the cross-chain interaction need to be compensated and will have utilized off-chain resources. As a result, we consider this exhibit null.

SYN-03M: Inconsistent Event Amount

Description:

The SynthesizeCompleted event has an inconsistent amount emitted, at one instance emitting the full amount inclusive of the minting fee and at the other emitting the amount sans the fee.

Example:

contracts/synth-contracts/Synthesis.sol
176ISyntFabric(fabric).synthesize(
177 address(this),
178 _metaMintTransaction.amount - _metaMintTransaction.stableBridgingFee,
179 syntReprAddr
180);
181
182ISyntFabric(fabric).synthesize(
183 bridge,
184 _metaMintTransaction.stableBridgingFee,
185 syntReprAddr
186);
187
188_metaMintTransaction.amount = _metaMintTransaction.amount - _metaMintTransaction.stableBridgingFee;
189
190emit SynthesizeCompleted(
191 _metaMintTransaction.txID,
192 _metaMintTransaction.to,
193 _metaMintTransaction.amount,
194 _metaMintTransaction.tokenReal
195);

Recommendation:

We advise the event emissions to be synced to ensure that off-chain processes properly process the amounts synthesize, especially in a layer-2 sensitive system such as a bridge.

Alleviation:

The event emissions were standardized to emit the amount sans the fee across the code.

SYN-04M: Inexistent Validation of Token Existence

Description:

The linked synthesization lookups do not guarantee that the address exists yet the code assumes so.

Example:

contracts/synth-contracts/Synthesis.sol
171address syntReprAddr = ISyntFabric(fabric).getSyntRepresentation(
172 _metaMintTransaction.tokenReal,
173 _metaMintTransaction.chainID
174);
175
176ISyntFabric(fabric).synthesize(
177 address(this),
178 _metaMintTransaction.amount - _metaMintTransaction.stableBridgingFee,
179 syntReprAddr
180);

Recommendation:

We advise this to be evaluated by a proper require check to increase code legibility and aid in debugging of the system.

Alleviation:

A require check was introduced ensuring that the syntReprAddr retrieved is non-zero.

SYN-05M: Potential of Repeat Invocation

Description:

The setMetaRouter function can be invoked an arbitrary number of times and set a sensitive contract variable.

Example:

contracts/synth-contracts/Synthesis.sol
448/**
449 * @notice Sets MetaRouter address
450 */
451function setMetaRouter(IMetaRouterV2 _metaRouter) external onlyOwner {
452 require(address(_metaRouter) != address(0), "Symb: metaRouter cannot be zero address");
453 metaRouter = _metaRouter;
454}

Recommendation:

We advise it to only be settable once as otherwise a malicious owner can front-run a potential synthesization by setting the metaRouter to a malicious contract prior to a transaction's execution by the network.

Alleviation:

The Symbiosis Finance team stated that while they are aware of the power of this feature, they consider it essential to their project and in order to alleviate concerns they will ensure that the owner of the contract will sit behind a multisignature wallet and timelock implementation. As such, we consider this exhibit adequately dealt with.