pragma solidity 0.5.17; import "./Locking4Reputation.sol"; /** * @title A scheme for external locking Tokens for reputation */ contract ExternalLocking4Reputation is Locking4Reputation { event Register(address indexed _beneficiary); address public externalLockingContract; string public getBalanceFuncSignature; // locker -> bool mapping(address => bool) public externalLockers; // beneficiary -> bool mapping(address => bool) public registrar; /** * @dev initialize * @param _avatar the avatar to mint reputation from * @param _reputationReward the total reputation this contract will reward * for the token locking * @param _claimingStartTime claiming starting period time. * @param _claimingEndTime the claiming end time. * claiming is disable after this time. * @param _redeemEnableTime redeem enable time . * redeem reputation can be done after this time. * @param _externalLockingContract the contract which lock the token. * @param _getBalanceFuncSignature get balance function signature * e.g "lockedTokenBalances(address)" */ function initialize( Avatar _avatar, uint256 _reputationReward, uint256 _claimingStartTime, uint256 _claimingEndTime, uint256 _redeemEnableTime, address _externalLockingContract, string calldata _getBalanceFuncSignature, bytes32 _agreementHash) external { require(_claimingEndTime > _claimingStartTime, "_claimingEndTime should be greater than _claimingStartTime"); externalLockingContract = _externalLockingContract; getBalanceFuncSignature = _getBalanceFuncSignature; super._initialize( _avatar, _reputationReward, _claimingStartTime, _claimingEndTime, _redeemEnableTime, 1, _agreementHash); } /** * @dev claim function * @param _beneficiary the beneficiary address to claim for * if _beneficiary == 0 the claim will be for the msg.sender. * @return claimId */ function claim(address _beneficiary, bytes32 _agreementHash) public returns(bytes32) { require(avatar != Avatar(0), "should initialize first"); address beneficiary; if (_beneficiary == address(0)) { beneficiary = msg.sender; } else { require(registrar[_beneficiary], "beneficiary should be register"); beneficiary = _beneficiary; } require(externalLockers[beneficiary] == false, "claiming twice for the same beneficiary is not allowed"); externalLockers[beneficiary] = true; (bool result, bytes memory returnValue) = // solhint-disable-next-line avoid-call-value,avoid-low-level-calls externalLockingContract.call(abi.encodeWithSignature(getBalanceFuncSignature, beneficiary)); require(result, "call to external contract should succeed"); uint256 lockedAmount; // solhint-disable-next-line no-inline-assembly assembly { lockedAmount := mload(add(returnValue, 0x20)) } return super._lock(lockedAmount, 1, beneficiary, 1, 1, _agreementHash); } /** * @dev register function * register for external locking claim */ function register(bytes32 _agreementHash) public onlyAgree(_agreementHash) { registrar[msg.sender] = true; emit Register(msg.sender); } }