diff --git a/contracts/polygon/connectors/socket/events.sol b/contracts/polygon/connectors/socket/events.sol new file mode 100644 index 00000000..2e35e168 --- /dev/null +++ b/contracts/polygon/connectors/socket/events.sol @@ -0,0 +1,13 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +contract Events { + event LogSocketBridge( + address token, + uint256 amount, + uint256 sourceChain, + uint256 targetChain, + address recipient + ); +} diff --git a/contracts/polygon/connectors/socket/helpers.sol b/contracts/polygon/connectors/socket/helpers.sol new file mode 100644 index 00000000..066620fd --- /dev/null +++ b/contracts/polygon/connectors/socket/helpers.sol @@ -0,0 +1,33 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.6; +pragma experimental ABIEncoderV2; + +import "./interface.sol"; +import { Basic } from "../../common/basic.sol"; +import { TokenInterface } from "../../common/interfaces.sol"; + +contract Helpers is Basic { + address internal immutable registry = + 0xc30141B657f4216252dc59Af2e7CdB9D8792e1B0; + + function _socketBridge(bytes memory _txData, uint256 _nativeTokenAmt) + internal + returns (bool _success) + { + (_success, ) = registry.call{ value: _nativeTokenAmt }(_txData); + } + + /** + * @dev Gets Allowance target from registry. + * @param _route route number + */ + function getAllowanceTarget(uint256 _route) + internal + view + returns (address _allowanceTarget) + { + RouteData memory data = ISocketRegistry(registry).routes(_route); + _allowanceTarget = data.route; + require(_allowanceTarget != address(0), "allowanceTarget-not-valid"); + } +} diff --git a/contracts/polygon/connectors/socket/interface.sol b/contracts/polygon/connectors/socket/interface.sol new file mode 100644 index 00000000..94884556 --- /dev/null +++ b/contracts/polygon/connectors/socket/interface.sol @@ -0,0 +1,13 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.6; +pragma experimental ABIEncoderV2; + +struct RouteData { + address route; + bool isEnabled; + bool isMiddleware; +} + +interface ISocketRegistry { + function routes(uint256) external view returns (RouteData memory); +} diff --git a/contracts/polygon/connectors/socket/main.sol b/contracts/polygon/connectors/socket/main.sol new file mode 100644 index 00000000..929a61b4 --- /dev/null +++ b/contracts/polygon/connectors/socket/main.sol @@ -0,0 +1,71 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.6; +pragma experimental ABIEncoderV2; + +/** + * @title Socket. + * @dev Multi-chain Bridge Aggregator. + */ + +import "./events.sol"; +import "./helpers.sol"; + +abstract contract SocketResolver is Helpers { + /** + * @dev Bridge Token. + * @notice Bridge Token on Socket. + * @param _token token address on source chain + * @param _txData tx data for calling + * @param _route route number + * @param _amount amount to bridge + * @param _targetChain Target chain ID + * @param _recipient address of the recipient on the target chain + */ + function bridge( + address _token, + bytes memory _txData, + uint256 _route, + uint256 _amount, + uint256 _targetChain, + address _recipient + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + bool isNative = _token == maticAddr; + uint256 nativeTokenAmt; + + if (isNative) { + _amount = _amount == uint256(-1) ? address(this).balance : _amount; + nativeTokenAmt = _amount; + } else { + TokenInterface tokenContract = TokenInterface(_token); + + _amount = _amount == uint256(-1) + ? tokenContract.balanceOf(address(this)) + : _amount; + tokenContract.approve(getAllowanceTarget(_route), _amount); + } + + require(_socketBridge(_txData, nativeTokenAmt), "Socket-swap-failed"); + + uint256 _sourceChain; + assembly { + _sourceChain := chainid() + } + + _eventName = "LogSocketBridge(address,uint256,uint256,uint256,address)"; + _eventParam = abi.encode( + _token, + _amount, + _sourceChain, + _targetChain, + _recipient + ); + } +} + +contract ConnectV2SocketPolygon is SocketResolver { + string public constant name = "Socket-v1.0"; +}