diff --git a/README.md b/README.md index 7a79639..9069b5a 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ MetaMask setup for Sokol: ## Deployed Addresses Sokol: -- Wrapped PNK: `0x03FCABBE7680ff0513349E643b11CE83A7434fD7` -- xKlerosLiquid: `0xec8726b782D77fC9Fdf64d12D895CA15956b9e0e` -- xKlerosLiquidExtraViews: `0x850753F8785471893d552e7Bdadcc2ccD8eB182F` +- Wrapped PNK: `0x9Bc02E9f5291adbb1f0Cf5C15ab1B400dccd3665` +- xKlerosLiquid: `0xb701ff19fBD9702DD7Ca099Ee7D0D42a2612baB5` +- xKlerosLiquidExtraViews: `0x1Aab57DD59afc98bff1D939b34974E9c8fc705fF` - PolicyRegistry: `0x0Bee63bC7220d0Bacd8A3c9d6B6511126CDfe58f` xDai: @@ -26,11 +26,17 @@ xDai: ## Stake 1. Get Kovan PNK from [faucet](https://kovan.etherscan.io/address/0x4e95b2e0ecb3bd394e1dddd775504820a746d3bd#writeContract). The Kovan PNK contract address is `0x1ee318dbc19267dbce08f54a66ab198f73ede356`. +1. [approve](https://kovan.etherscan.io/address/0x1ee318dbc19267dbce08f54a66ab198f73ede356#writeContract) the amount of PNK that you want to stake to the foreign token bridge contract (`0xa960d095470f7509955d5402e36d9db984b5c8e2`). +1. [relayTokensAndCall](https://kovan.etherscan.io/address/0xa960d095470f7509955d5402e36d9db984b5c8e2#writeProxyContract) in order to bridge the tokens to Sokol. Use token: `0x1ee318dbc19267dbce08f54a66ab198f73ede356`, _receiver: `0x9Bc02E9f5291adbb1f0Cf5C15ab1B400dccd3665`, _value: amount of PNK to bridge, _data: the address that will receive the tokens on Sokol padded to 32 bytes. +1. Now, you are ready to [stake](https://blockscout.com/poa/sokol/address/0xb701ff19fBD9702DD7Ca099Ee7D0D42a2612baB5/write-proxy) in the Sokol general court by calling `setStake`. + +## Stake (using Omnibridge) +1. Get Kovan PNK from [faucet](https://kovan.etherscan.io/address/0x4e95b2e0ecb3bd394e1dddd775504820a746d3bd#writeContract). The Kovan PNK contract address is `0x1ee318dbc19267dbce08f54a66ab198f73ede356`. 1. Go to the [token bridge](https://sokol-omnibridge.web.app/bridge) and convert Kovan PNK into Sokol PNK. The Sokol PNK contract address is `0x184A7Fc4fa965D18Af84C6d97dfed8C4561ff8c2`. -1. Sokol PNK are not directly used for staking. Instead, the token is wrapped in order to let xKlerosLiquid (the courts) be the controller of the PNK contract. To convert Sokol PNK into Sokol Wrapped PNK, first [approve](https://blockscout.com/poa/sokol/address/0x184A7Fc4fa965D18Af84C6d97dfed8C4561ff8c2/write-proxy) the address `0x03FCABBE7680ff0513349E643b11CE83A7434fD7` the amount you want to convert and then call [deposit](https://blockscout.com/poa/sokol/address/0x03FCABBE7680ff0513349E643b11CE83A7434fD7/write-proxy). -1. Now, you are ready to [stake](https://blockscout.com/poa/sokol/address/0xec8726b782D77fC9Fdf64d12D895CA15956b9e0e/write-proxy) in the Sokol general court by calling `setStake`. +1. Sokol PNK are not directly used for staking. Instead, the token is wrapped in order to let xKlerosLiquid (the courts) be the controller of the PNK contract. To convert Sokol PNK into Sokol Wrapped PNK, first [approve](https://blockscout.com/poa/sokol/address/0x184A7Fc4fa965D18Af84C6d97dfed8C4561ff8c2/write-proxy) the address `0x9Bc02E9f5291adbb1f0Cf5C15ab1B400dccd3665` the amount you want to convert and then call [deposit](https://blockscout.com/poa/sokol/address/0x9Bc02E9f5291adbb1f0Cf5C15ab1B400dccd3665/write-proxy). +1. Now, you are ready to [stake](https://blockscout.com/poa/sokol/address/0xb701ff19fBD9702DD7Ca099Ee7D0D42a2612baB5/write-proxy) in the Sokol general court by calling `setStake`. ## Unstake 1. Unstake from the Sokol general court. -1. You can use `withdrawAndConvertToPNK()` [method](https://blockscout.com/poa/sokol/address/0x03FCABBE7680ff0513349E643b11CE83A7434fD7/write-contract) to directly convert the Sokol Wrapped PNK into Kovan PNK. If you use this method, it is possible to set the receiver. On the Kovan chain, the tokens have to be claimed though. Go to the [token bridge](https://sokol-omnibridge.web.app/bridge), connect MetaMask with your Kovan account and claim your tokens. -1. If you rather use the token bridge, call `withdraw()` [method](https://blockscout.com/poa/sokol/address/0x03FCABBE7680ff0513349E643b11CE83A7434fD7/write-contract) instead. Then go to the [token bridge](https://sokol-omnibridge.web.app/bridge) convert your tokens. +1. You can use `withdrawAndConvertToPNK()` [method](https://blockscout.com/poa/sokol/address/0x9Bc02E9f5291adbb1f0Cf5C15ab1B400dccd3665/write-contract) to directly convert the Sokol Wrapped PNK into Kovan PNK. If you use this method, it is possible to set the receiver. On the Kovan chain, the tokens have to be claimed though. Go to the [token bridge](https://sokol-omnibridge.web.app/bridge), connect MetaMask with your Kovan account and claim your tokens. +1. If you rather use the token bridge, call `withdraw()` [method](https://blockscout.com/poa/sokol/address/0x9Bc02E9f5291adbb1f0Cf5C15ab1B400dccd3665/write-contract) instead. Then go to the [token bridge](https://sokol-omnibridge.web.app/bridge) convert your tokens. diff --git a/contracts/tokens/WrappedPinakion.sol b/contracts/tokens/WrappedPinakion.sol index 7329c13..d3c7dc3 100644 --- a/contracts/tokens/WrappedPinakion.sol +++ b/contracts/tokens/WrappedPinakion.sol @@ -1,7 +1,7 @@ /** * https://contributing.kleros.io/smart-contract-workflow * @authors: [@fnanni-0] - * @reviewers: [@unknownunknown1, @MerlinEgalite, @hbarcelos, @shalzz] + * @reviewers: [@unknownunknown1*, @MerlinEgalite*, @hbarcelos*, @shalzz*] * @auditors: [] * @bounties: [] * @deployments: [] @@ -104,11 +104,31 @@ contract WrappedPinakion is Initializable { * @param _amount The amount of wrapped pinakions to mint. */ function deposit(uint _amount) external { - _mint(_amount); + _mint(msg.sender, _amount); require(xPinakion.transferFrom(msg.sender, address(this), _amount), "Sender does not have enough approved funds."); } + /** @dev IERC20 Receiver functionality. + * Converts bridged PNK (xPinakion) into wrapped PNK which can be staked in KlerosLiquid. + * If the tokenBridge is calling this function, then this contract has already received + * the xPinakion tokens. + * @param _token The token address the _amount belongs to. + * @param _amount The amount of wrapped pinakions to mint. + * @param _data Calldata containing the address of the recipient. + * Notice that the address has to be padded to 32 bytes. + */ + function onTokenBridged(address _token, uint _amount, bytes _data) external { + require(msg.sender == address(tokenBridge), "Sender not authorized."); + require(_token == address(xPinakion), "Token bridged is not xPinakion."); + + address recipient; + assembly { + recipient := calldataload(0x84) + } + _mint(recipient, _amount); + } + /** @dev Withdraws bridged pinakions. * @param _amount The amount of bridged pinakions to withdraw. */ @@ -223,12 +243,13 @@ contract WrappedPinakion is Initializable { * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. + * @param _recipient The address which will receive the minted tokens. * @param _amount The amount that will be created. */ - function _mint(uint256 _amount) internal { + function _mint(address _recipient, uint256 _amount) internal { totalSupply = totalSupply.add(_amount); - balances[msg.sender] = balances[msg.sender].add(_amount); - emit Transfer(address(0x0), msg.sender, _amount); + balances[_recipient] = balances[_recipient].add(_amount); + emit Transfer(address(0x0), _recipient, _amount); } /** @dev Destroys `_amount` tokens from the caller. Cannot burn locked tokens.