Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forced Transfer #253

Merged
merged 6 commits into from
Sep 16, 2018
Merged

Forced Transfer #253

merged 6 commits into from
Sep 16, 2018

Conversation

thegostep
Copy link

@thegostep thegostep commented Sep 11, 2018

Please check if the PR fulfills these requirements

  • The commit message follows our Submission guidelines

  • Docs have been added / updated (for bug fixes / features)

  • Tests for the changes have been added (for bug fixes / features)

What kind of change does this PR introduce?

(Bug fix, feature, docs update, ...)

What is the current behavior?

(You can also link to an open issue here)

What is the new behavior?

(Define and describe any new functionality. Clarify if this is a feature change)

Does this PR introduce a breaking change?

(What changes might users need to make in their application due to this PR?)

Any Other information:

@pabloruiz55
Copy link
Contributor

pabloruiz55 commented Sep 11, 2018

@thegostep I feel this could be done as a module that the issuer can add so we keep the same logic of permissions. The forcedTransfer method would only be callable by onlyModuleOrOwner and then we have a withPerm for controllers on that module. Else, we are duplicating the permissions logic.
@adamdossa

* @param _value amount of tokens to transfer
* @param _data data attached to the transfer by controller for event
*/
function controllerTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController {
Copy link
Contributor

@pabloruiz55 pabloruiz55 Sep 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's _data for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a reason string explaining why the transfer occured which gets logged as an event

@thegostep
Copy link
Author

thegostep commented Sep 11, 2018

@thegostep I feel this could be done as a module that the issuer can add so we keep the same logic of permissions. The forcedTransfer method would only be callable by onlyModuleOrOwner and then we have a withPerm for controllers on that module. Else, we are duplicating the permissions logic.

@pabloruiz55 I agree this makes sense. Should this be a new module or added to the general permission manager?

@adamdossa
Copy link
Contributor

Not sure how a module would adjust balances though unless I am missing something? It would need to do it via the ST contract, which doesn't have a setter for this variable.

We could introduce a setter for balances (which is only callable by a module of a certain type) but not sure that is the best approach.

@pabloruiz55 related to this, do you think forcedTransfer should respect the verifyTransfer rules? I am thinking it should do (this would mean that the controller can only force transfer where it is possible given the attached TM modules - they could of course use the MATM if needed as well).

@thegostep how important do you think it is to be able to return a list of controller addresses on-chain (rather than by event scanning) - this does make the logic more complex as you have to keep the indexes etc. and clean up behind yourself.

@pabloruiz55
Copy link
Contributor

pabloruiz55 commented Sep 11, 2018 via email

@adamdossa
Copy link
Contributor

@thegostep Hey Stephane - we discussed this on the call today. Some thoughts:

  • we don't need a list of controllers - a single address should be fine. If the issuer wants to they can always make that address a multi-sig or other contract with whatever authorisation mechanism they want.

  • I think the simplest approach is to have a single controller address which has access to the forceTransfer function and which can be set only by the token owner.

  • it should be possible for the issuer to indicate that they won't (and never will) use this feature. For now we can make this depend on the feature registry (i.e. similar to freezing minting) - i.e. only allow the issuer to turn off the ability permanently for forced transfers if isEnabled("disableForcedTransfersAllowed") is true.

  • there was a discussion around whether this should be moved out to a module, but I don't think this is necessary at this point. If we have contract size issues later then it is something we could re-consider.

* @param _value amount of tokens to transfer
* @param _data data attached to the transfer by controller for event
*/
function controllerTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this function also need to be added to the constructor?
transferFunctions[bytes4(keccak256(...))] = true;
@adamdossa

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only if it calls verifyTransfer()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern can be revisited using internal / private functions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - if it is going to call verifyTransfer then it should do so that TMs know they should record any side-effects of the transfer.

One option here is to call verifyTransfer but disregard the result (or just include the result in the ControlledTransfer event).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of adding the result to the event

* @param _value amount of tokens to transfer
* @param _data data attached to the transfer by controller to emit in event
*/
function controllerTransfer(address _from, address _to, uint256 _value, bytes _data) external returns(bool);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename it to forceTransfer as it is a bit more evident what this does.

@pabloruiz55
Copy link
Contributor

The way I see this working is that the forcedTransfer method should be onlyOperator (which we already have) but also isEnabled as opposed to having the isEnabled at the setOperator level.

So, as long as isEnabled == true this function can be called by the set operator. And then the setOperator function can be greatly simplified so the issuer can set it to an address or 0x0 at any moment.

@pabloruiz55
Copy link
Contributor

@adamdossa looks ready for you to review.

@adamdossa
Copy link
Contributor

@pabloruiz55 Reviewed and modified function names. If you can approve I'll merge once tests run.

@pabloruiz55 pabloruiz55 merged commit ddcdb42 into development-1.5.0 Sep 16, 2018
@adamdossa adamdossa deleted the forcedTransfer branch January 11, 2019 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants