The irony of the comments in this thread decrying this as a classic example of too much abstraction is that the reason you rarely see three-star variables in C is that, while it's common to have long chains of pointers (and in languages where ~everything is a pointer~ most things are pointers by default, like Python, Java, or JavaScript, you definitely have pointer chains that are much longer than 4!), what is uncommon (but not nonexistent) is the need to manipulate more than two levels at once — you'll have one, maybe two, levels of pointers, but anything deeper is probably going to be hidden in a struct whose internals you don't have to care about (i.e. abstracted away). The same argument applies to channels, which are roughly to concurrent code what pointers are to sequential code: the fatal flaw here, if there is one, is not too much abstraction, but perhaps too little abstraction.
But then, I don't know the codebase — maybe a `chan chan` was exactly the right abstraction for what they were trying to write :) Certainly in highly-concurrent languages like Erlang, it is very standard practice to send a PID to another PID, for example to identify the process that should receive the reply to the message.