Omniscia Symbiosis Finance Audit

Portal Manual Review Findings

Portal Manual Review Findings

POR-01M: Inexistent Access Control for Reverts

Description:

The revertBurnRequest 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/Portal.sol
373/**
374 * @notice Revert burnSyntheticToken() operation
375 * @dev Can called only by bridge after initiation on a second chain
376 * @dev Further, this transaction also enters the relay network and is called on the other side under the method "revertBurn"
377 * @param _txID the synthesize transaction that was received from the event when it was originally called burn on the Synthesize contract
378 * @param _receiveSide Synthesis address on another network
379 * @param _oppositeBridge Bridge address on another network
380 * @param _chainId Chain id of the network
381 */
382function revertBurnRequest(
383 uint256 _stableBridgingFee,
384 bytes32 _txID,
385 address _receiveSide,
386 address _oppositeBridge,
387 uint256 _chainId
388) external payable whenNotPaused {
389 bytes32 externalID = keccak256(abi.encodePacked(_txID, address(this), block.chainid));
390
391 require(
392 unsynthesizeStates[externalID] != UnsynthesizeState.Unsynthesized,
393 "Symb: Real tokens already transfered"
394 );
395 unsynthesizeStates[externalID] = UnsynthesizeState.RevertRequest;
396
397 {
398 bytes memory out = abi.encodeWithSelector(
399 bytes4(keccak256(bytes("revertBurn(uint256,bytes32)"))),
400 _stableBridgingFee,
401 externalID
402 );
403 IBridge(bridge).transmitRequestV2(
404 out,
405 _receiveSide,
406 _oppositeBridge,
407 _chainId
408 );
409 }
410
411 emit RevertBurnRequest(_txID, _msgSender());
412}

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.

POR-02M: Improper receive Function

TypeSeverityLocation
Logical FaultPortal.sol:L585

Description:

The Portal contract is able to receive native assets, however, no function exists in the contract that utilizes funds received as an argument.

Example:

contracts/synth-contracts/Portal.sol
585receive() external payable {}

Recommendation:

We advise the function to be omitted from the contract to avoid locked native assets.

Alleviation:

The receive function has been omitted from the codebase as per our recommendation.

POR-03M: 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/Portal.sol
444/**
445 * @notice Sets MetaRouter address
446 */
447function setMetaRouter(IMetaRouterV2 _metaRouter) external onlyOwner {
448 require(address(_metaRouter) != address(0), "Symb: metaRouter cannot be zero address");
449 metaRouter = _metaRouter;
450}

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.