Assimilators should implement an interface
The Assimilators are one of the core components within the application. They are used to move the tokens and can be thought of as a “middleware” between the Shell Protocol application and any other supported tokens.\\nThe methods attached to the assimilators are called throughout the application and they are a critical component of the whole system. Because of this fact, it is extremely important that they behave correctly.\\nA suggestion to restrict the possibility of errors when implementing them and when using them is to make all of the assimilators implement a unique specific interface. This way, any deviation would be immediately observed, right when the compilation happens.\\nConsider this example. The user calls `swapByOrigin`.\\n```\\nfunction swapByOrigin (address \\_o, address \\_t, uint256 \\_oAmt, uint256 \\_mTAmt, uint256 \\_dline) public notFrozen returns (uint256 tAmt\\_) {\\n\\n    return transferByOrigin(\\_o, \\_t, \\_dline, \\_mTAmt, \\_oAmt, msg.sender);\\n\\n}\\n```\\n\\nWhich calls `transferByOrigin`. In `transferByOrigin`, if the origin index matches the target index, a different execution branch is activated.\\n```\\nif (\\_o.ix == \\_t.ix) return \\_t.addr.outputNumeraire(\\_rcpnt, \\_o.addr.intakeRaw(\\_oAmt));\\n```\\n\\nIn this case we need the output of `_o.addr.intakeRaw(_oAmt)`.\\nIf we pick a random assimilator and check the implementation, we see the function `intakeRaw` needs to return the transferred amount.\\n```\\n// takes raw cdai amount, transfers it in, calculates corresponding numeraire amount and returns it\\nfunction intakeRaw (uint256 \\_amount) public returns (int128 amount\\_) {\\n\\n    bool success = cdai.transferFrom(msg.sender, address(this), \\_amount);\\n\\n    if (!success) revert("CDai/transferFrom-failed");\\n\\n    uint256 \\_rate = cdai.exchangeRateStored();\\n\\n    \\_amount = ( \\_amount \\* \\_rate ) / 1e18;\\n\\n    cdai.redeemUnderlying(\\_amount);\\n\\n    amount\\_ = \\_amount.divu(1e18);\\n\\n}\\n```\\n\\nHowever, with other implementations, the returns do not match. In the case of `MainnetDaiToDaiAssimilator`, it returns 2 values, which will make the `Loihi` contract work in this case but can misbehave in other cases, or even fail.\\n```\\n// transfers raw amonut of dai in, wraps it in cDai, returns numeraire amount\\nfunction intakeRaw (uint256 \\_amount) public returns (int128 amount\\_, int128 balance\\_) {\\n\\n    dai.transferFrom(msg.sender, address(this), \\_amount);\\n\\n    amount\\_ = \\_amount.divu(1e18);\\n\\n}\\n```\\n\\nMaking all the assimilators implement one unique interface will enforce the functions to look the same from the outside.
Create a unique interface for the assimilators and make all the contracts implement that interface.
```\\nfunction swapByOrigin (address \\_o, address \\_t, uint256 \\_oAmt, uint256 \\_mTAmt, uint256 \\_dline) public notFrozen returns (uint256 tAmt\\_) {\\n\\n    return transferByOrigin(\\_o, \\_t, \\_dline, \\_mTAmt, \\_oAmt, msg.sender);\\n\\n}\\n```\\n