pragma solidity ^0.6.2; pragma experimental ABIEncoderV2; interface GeneralERC20 { function transfer(address to, uint256 amount) external; function transferFrom(address from, address to, uint256 amount) external; function approve(address spender, uint256 amount) external; function balanceOf(address spender) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); } interface ADXToken { function approve(address spender, uint256 amount) external; function swap(uint256 amount) external; function balanceOf(address spender) external view returns (uint); } struct Bond { uint amount; bytes32 poolId; uint nonce; } interface Staking { function addBond(Bond memory bond) external; } contract IdentityProxy { mapping (address => uint8) public privileges; constructor() public { privileges[address(this)] = 2; privileges[0xd6e371526cdaeE04cd8AF225D42e37Bc14688D9E] = 2; // @TODO dynamic GeneralERC20 oldToken = GeneralERC20(0x4470BB87d77b963A013DB939BE332f927f2b992e); ADXToken newToken = ADXToken(0xADE00C28244d5CE17D72E40330B1c318cD12B7c3); uint balanceOld = oldToken.balanceOf(address(this)); if (balanceOld > 0) { oldToken.approve(address(newToken), balanceOld); newToken.swap(balanceOld); } uint balanceNew = newToken.balanceOf(address(this)); if (balanceNew > 0) { Staking staking = Staking(0x4846C6837ec670Bbd1f5b485471c8f64ECB9c534); newToken.approve(address(staking), balanceNew); staking.addBond(Bond({ amount: balanceNew, poolId: 0x2ce0c96383fb229d9776f33846e983a956a7d95844fac57b180ed0071d93bb28, nonce: block.timestamp })); } } fallback() external { address to = address(0x96E3CB4B4632eD45363FF2c9f0FbEc9B583D9d3A); assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(sub(gas(), 10000), to, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 {revert(0, returndatasize())} default {return (0, returndatasize())} } } }